Tôi có một ứng dụng sandbox Seam 3 sử dụng JBoss 7, Hibernate như thực hiện JPA mặc định và JSF làm giao diện người dùng web.JPA/Hibernate phát ra không có CẬP NHẬT trên cam kết trong môi trường EJB/Seam
Tôi gặp sự cố, rằng UPDATE SQL bị nuốt theo mặc định.
EJB stateful của tôi trong phạm vi trò chuyện duy trì một mở rộng scoped EntityManager và một Entity, container Giao dịch Managed (Yêu cầu mới)
- Các EntityManager được tiêm
- EJB sử dụng EM để nạp Entity và giữ nó trong một lĩnh vực
- ứng dụng JSF truy cập vào EJB và thực thể của nó, thay đổi một lĩnh vực Chuỗi
- Calles ứng dụng JSF phương pháp "Save" trong EJB
- trong save() Tôi kiểm tra, nếu trường Thực thể đã được thay đổi -> nó đã được thay đổi đúng cách
- Tôi không làm gì nữa, vùng chứa cam kết giao dịch sau khi lưu() xong.
- Vấn đề: Không cập nhật SQL nào được thực hiện đối với DB.
Nếu tôi mở rộng lưu() bằng cách:
a) entityManager.contains (thực thể) UPDATE được thực hiện như mong đợi (kết quả là "true")
HOẶC
b) entityManager.persist (thực thể) UPDATE được thực hiện như mong đợi
Q: Theo tôi hiểu các thông số không phải là a) hoặc b) phải được yêu cầu, vì thực thể vẫn được quản lý trong toàn bộ quá trình. Tôi không hiểu, tại sao a) có tác dụng tiết kiệm. Tôi có thể chụp ảnh b) có tác dụng tiết kiệm, nhưng không cần thiết, phải không?
Mọi lời giải thích đều được hoan nghênh.
Đây là EJB của tôi:
@Named
@ConversationScoped
@Stateful
@TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)
public class LanguageBean {
@PersistenceContext(type = PersistenceContextType.EXTENDED)
private EntityManager em;
@Inject
private UserTransaction transaction;
private Language value;
@Inject
Conversation conversation;
public LanguageBean() {
super();
}
@Begin
public void selectLanguage(Long anId) {
conversation.setTimeout(10 * 60 * 1000);
if (anId != null) {
value = em.find(Language.class, anId);
}
}
@BeforeCompletion
public void transactionComplete(){
System.out.println("transactionComplete");
}
public Language getValue() {
return value;
}
@Produces
@Named
@ConversationScoped
public Language getLanguage() {
return getValue();
}
public void setValue(Language aValue) {
value = aValue;
}
@End
public String save() {
// displays the changed attribute:
System.out.println("save code: "+value.getCode());
// why is either this required:
// boolean tempContains = em.contains(value);
// System.out.println("managed: "+tempContains);
// or: why is persist required:
em.persist(value);
return "languages?faces-redirect=true";
}
@End
public String cancel() throws SystemException {
transaction.setRollbackOnly();
return "languages?faces-redirect=true";
}
}
tôi phát hiện ra entityManager.flush() cũng giải quyết được vấn đề. Nhưng tôi không hiểu tại sao điều này dường như được yêu cầu. Từ thông số JPA: "Khi giao dịch JTA cam kết, nhà cung cấp phải xóa tất cả trạng thái thực thể đã sửa đổi thành cơ sở dữ liệu ". – user1187037
có thể một nơi nào đó phiên FlushMode của phiên ngủ đông được đặt thành không? – Firo