views:

125

answers:

2

I've got a problem with the removal of entities in my JPA application: basically, I do in this EJB Business method:

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

and this last query always throws an EntityNotFoundException (deleted entity passed to persist: [...TagPhoto#])

I think I understand the meaning of this exception, like a synchronization problem caused by my Remove, but how can I get rid of it?

EDIT: here is the stack of the exception:

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)

and the mapping between 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;
}

(it was automatically generated by Netbeans when I created the project)

EDIT: Does it mean that tagPhoto != tagPhoto.getTag().getTagPhotoList().get(...) != tagPhoto.getPhoto().getTagPhotoList().get(...)?

and how shall I remove them? iterator.remove should not be of any use, and I would think that three em.remove() would do three times the same operation ...

A: 

To be honest, it's hard to say without the mappings (especially the cascading options), without the exact stack trace and without the real code as the pseudo code is very likely not showing the real problem. So this answer is more a shot in the dark (and you should consider posting the mentioned details).

My guess is that you're calling remove() on a TagPhoto instance that you are not removing from the one-to-many association. So when the EntityManager tries to update the parent Photo, it may indeed try to persist a deleted entity, hence the exception.

Update: You need to remove the TagPhoto instance from both collections that contain it:

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

Note that things are actually a bit more complicated because NetBeans generated an Entity for the join table (TagPhoto). It would be a bit easier if you had a many-to-many association between Photo and Tag. But in any case, when you remove an entity, you need to remove it from associations, JPA won't do that for you.

Pascal Thivent
I guess that your idea is part of my problem, I only remove the entity itself, but I don't know what to do with the associations (I expected JPA to do very thing for me ...)
Kevin
@Kevin No, you have to update the collections manually i.e. to remove the `TagPhoto` instance from both `tagPhotoList` (in `Photo` and `Tag`) or JPA will try to persist them back (since they are still part of the associations). That's very likely the root cause of the problem.
Pascal Thivent
A: 

Might be a problem with the synchronization. Try to call Session.flush() before you create the TagPhoto.

Develman
no, I tried to flush the EntityManager just after the remove, and the same exception is thrown
Kevin