EntityManager.remove()不会抛出预期的异常

时间:2018-02-23 23:03:01

标签: java jpa

根据the JavaDocremove的{​​{1}}方法会抛出com.javax.persistence.EntityManager

  

如果实例不是实体或是分离的实体

鉴于此,为什么这段代码不会抛出异常:

IllegalArgumentException

// create an Author object: this is a POJO Author a = new Author("George Orwell"); dao.delete(a); 的{​​{1}}方法只是

delete

如果我添加行

DAO

public void delete(T entity) throws IllegalArgumentException, TransactionRequiredException { em.getTransaction().begin(); em.remove(entity); em.getTransaction().commit(); } 方法,它会打印System.out.println(em.contains(entity)); 。这似乎是“分离实体”的定义,为什么不抛出异常呢?

1 个答案:

答案 0 :(得分:2)

此代码不会删除分离的实体:

Author a = new Author("George Orwell");  // transient entity

dao.delete(a); // delete an entity unknown for the context. 
               // The EM silently ignores that

它删除一个瞬态实体,这是一个从未由持久化上下文管理的实体。

要删除分离的实体,首先将其附加到持久性上下文:

Author a = new Author("George Orwell");  // transient entity

em.refresh(a); // attach the entity to the persistence context. 
               // persist() or merge() would also attach it

em.detach(a);  // detach it from the context

em.delete(a);  // delete a detached entity.
               // The EM throws llegalArgumentException

如果您的JPA实现符合规范,则应抛出IllegalArgumentException

至少,这就是Hibernate处理delete()操作所做的事情:

package org.hibernate.event.internal;
...
public class DefaultDeleteEventListener implements DeleteEventListener {
    ...
    @Override
    protected void performDetachedEntityDeletionCheck(DeleteEvent event) {
        EventSource source = event.getSession();
        String entityName = event.getEntityName();
        EntityPersister persister = source.getEntityPersister( entityName, event.getObject() );
        Serializable id =  persister.getIdentifier( event.getObject(), source );
        entityName = entityName == null ? source.guessEntityName( event.getObject() ) : entityName; 
        throw new IllegalArgumentException("Removing a detached instance "+ entityName + "#" + id);
    }
    ...
}