这不起作用 - 我总是抛出IllegalArgumentException,并提出"尝试合并分离并再次尝试删除"的建议.
@PersistenceContext private EntityManager em;
@Resource private UserTransaction utx;
public void delete(EN entity) {
if (entity == null) return; // null-safe
EN target = entity;
try {
if (!em.contains(entity)) {
System.out.println("delete() entity not managed: " + entity);
utx.begin();
target = em.merge(entity);
utx.commit();
System.out.print("delete() this entity should now be managed: " + em.contains(target));
}
utx.begin();
em.remove(target);
utx.commit();
} catch (RollbackException ex) {
Logger.getLogger(this.getClass().getName()).log(Level.SEVERE, null, ex);
} catch (HeuristicMixedException ex) {
Logger.getLogger(this.getClass().getName()).log(Level.SEVERE, null, ex);
} catch (HeuristicRollbackException ex) {
Logger.getLogger(this.getClass().getName()).log(Level.SEVERE, null, ex);
} catch (SecurityException ex) {
Logger.getLogger(this.getClass().getName()).log(Level.SEVERE, null, ex);
} catch (IllegalStateException ex) {
Logger.getLogger(this.getClass().getName()).log(Level.SEVERE, null, ex);
} catch (NotSupportedException ex) {
Logger.getLogger(this.getClass().getName()).log(Level.SEVERE, null, ex);
} catch (SystemException ex) {
Logger.getLogger(this.getClass().getName()).log(Level.SEVERE, null, ex);
}
}
Run Code Online (Sandbox Code Playgroud)
输出日志显示以下内容:
INFO: delete() entity not managed: com.database.SomeTable[ id=2 ]
INFO: delete() this entity should now be managed: false
Run Code Online (Sandbox Code Playgroud)
换句话说,merge()不返回托管实体.谁能发现我做错了什么?
第二个问题:有没有办法在一个交易中而不是两个交易中执行此操作?
这是使用GlassFish 3.1中的EclipseLink.
这段代码创建了两个事务:
if (!em.contains(entity)) {
System.out.println("delete() entity not managed: " + entity);
utx.begin();
target = em.merge(entity);
utx.commit();
System.out.print("delete() this entity should now be managed: " + em.contains(target));
}
utx.begin();
em.remove(target);
utx.commit();
Run Code Online (Sandbox Code Playgroud)
虽然实体合并到持久性上下文中是正确的,但它仅适用于第一个事务,而不适用于两者.在第二个事务中,与事务关联的持久性上下文将再次找到作为参数传递的分离对象,如下所示:
em.remove(target);
Run Code Online (Sandbox Code Playgroud)
因为,以前utx.commit()会分开引用target.
要解决此问题,必须将实体合并到持久性上下文中,并在分离引用之前删除同一事务中的实体:
if (!em.contains(entity)) {
System.out.println("delete() entity not managed: " + entity);
utx.begin();
target = em.merge(entity);
em.remove(target);
utx.commit();
System.out.print("delete() this entity should now be deleted: " + (!em.contains(target)) );
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
8003 次 |
| 最近记录: |