我在JPA应用程序中删除实体时遇到问题:基本上,我在此EJB Business方法中这样做:

load photo list ;
for each photo {
    //UPDATE
    remove TagPhoto element from @OneToMany relation
    //DISPLAY
    create query involving TagPhoto
    ...
}


并且最后一个查询总是抛出EntityNotFoundException(已删除的实体传递给持久化对象:[... TagPhoto#])

我想我理解此异常的含义,就像我的Remove引起的同步问题一样,但是如何摆脱它呢?

编辑:这是异常的堆栈:

Caused by: javax.persistence.EntityNotFoundException: deleted entity passed to persist: [net.wazari.dao.entity.TagPhoto#<null>]
    at org.hibernate.ejb.AbstractEntityManagerImpl.throwPersistenceException(AbstractEntityManagerImpl.java:621)
    at org.hibernate.ejb.QueryImpl.getResultList(QueryImpl.java:74)
    at net.wazari.dao.jpa.TagFacade.loadVisibleTags(TagFacade.java:108)


以及Tag-TagPhoto-Photo之间的映射

public class Tag implements Serializable {
    ...
    @OneToMany(cascade = CascadeType.ALL, mappedBy = "tag")
    private List<TagPhoto> tagPhotoList;
}
public class TagPhoto implements Serializable {
    ...
    @JoinColumn(name = "Tag", referencedColumnName = "ID")
    @ManyToOne(optional = false)
    private Tag tag;
    @JoinColumn(name = "Photo", referencedColumnName = "ID")
    @ManyToOne(optional = false)
    private Photo photo;
}
public class Photo implements Serializable {
    ...
    @OneToMany(cascade = CascadeType.ALL , mappedBy = "photo")
    private List<TagPhoto> tagPhotoList;
}


(它是我创建项目时由Netbeans自动生成的)

编辑:这是否意味着tagPhoto != tagPhoto.getTag().getTagPhotoList().get(...) != tagPhoto.getPhoto().getTagPhotoList().get(...)

以及如何删除它们? iterator.remove不应有任何用处,我认为三个em.remove()可以执行相同操作的三倍...

最佳答案

老实说,很难说没有映射(尤其是级联选项),没有确切的堆栈跟踪信息和真正的代码,因为伪代码很可能不会显示真正的问题。因此,此答案更像是在黑暗中拍摄(您应该考虑发布提到的细节)。

我的猜测是您要在未从一对多关联中删除的remove()实例上调用TagPhoto。因此,当EntityManager尝试更新父级Photo时,实际上可能会尝试保留已删除的实体,因此是例外。

更新:您需要从包含它的两个集合中删除TagPhoto实例:

photo.getTagPhotoList().remove(tagPhoto);
...
tag.getTagPhotoList().remove(tagPhoto);
...
em.remove(tagPhoto);


请注意,实际上事情有些复杂,因为NetBeans为联接表(TagPhoto)生成了一个实体。如果您在PhotoTag之间建立了多对多关联,那会容易一些。但是无论如何,当您删除实体时,需要将其从关联中删除,JPA不会为您这样做。

09-05 15:38