我有一个使用 JBoss 7 的 Seam 3 沙盒应用程序,Hibernate 作为默认 JPA 实现,JSF 作为 Web 前端。
我有一个问题,默认情况下 SQL UPDATE 被吞下。
我在对话范围内的有状态 EJB 维护一个扩展范围的 EntityManager 和一个实体、容器管理事务(需要新的)
- EntityManager 被注入
- EJB 使用 EM 加载实体并将其保存在字段中
- JSF 应用程序访问 EJB 及其实体,更改字符串字段
- JSF 应用程序在 EJB 中调用“保存”方法
- 在 save() 中,我检查实体字段是否已更改 -> 是否已正确更改
- 我什么也不做,容器在 save() 完成后提交事务。
- 问题:没有对数据库执行 SQL 更新。
如果我通过以下方式扩展 save():
a) entityManager.contains(entity) UPDATE 按预期执行(结果为“true”)
或者
b) entityManager.persist(entity) UPDATE 按预期执行
问:据我了解,a) 或 b) 中的规范都不是必需的,因为实体在整个过程中仍然受到管理。我不明白,为什么 a) 对储蓄有影响。我可以成像 b) 对保存有影响,但它不应该是必需的,不是吗?
欢迎任何解释。
这是我的 EJB:
@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";
}
}