开发者

How do I make my entity object managed so I can remove it?

This doesn't work -- I always get the IllegalArgumentException thrown with the advice to "try merging the detached and try the remove again."

@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 (Sy开发者_如何转开发stemException ex) {
        Logger.getLogger(this.getClass().getName()).log(Level.SEVERE, null, ex);
    }
}

The output log shows the following:

INFO: delete() entity not managed: com.database.SomeTable[ id=2 ]  
INFO: delete() this entity should now be managed: false

In other words the merge() does not return a managed entity. Can anyone spot what I did wrong?

Second question: is there a way to do this in one transaction rather than two?

This is with EclipseLink inside GlassFish 3.1.


This snippet of code creates two transactions:

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();

While it is true that the entity is merged into the persistence context, it is true only of the first transaction, and not for both. In the second transaction, the persistence context associated with the transaction will again find a detached object passed as an argument, in the following line:

em.remove(target);

since, the previous utx.commit() would have detached the reference to target.

To fix this, you must merge the entity into the persistence context, and delete the entity in the same transaction, before the reference is detached:

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)) );
}


After commiting your persistence context should be gone. So your println test after the commit will fail, because the "target" object is not managed anymore.

Do all your stuff within one transaction and it should work. You just have to start your transaction after your "try" begins.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜