It will take a moment for me to explain this, so please stay with me. I have table NewsFeed that has OneToMany relationship with itself.
@Entity
public class NewsFeed(){
...
@ManyToOne(optional=true, fetch=FetchType.LAZY)
@JoinColumn(name="REPLYTO_ID")
private NewsFeed replyTo;
@OneToMany(mappedBy="replyTo", cascade=CascadeType.ALL)
private List<NewsFeed> replies = new ArrayList<NewsFeed>();
public void addReply(NewsFeed reply){
replies.add(reply);
reply.setReplyTo(this);
}
public void removeReply(NewsFeed reply){
replies.remove(reply);
}
}
So you can think like this. Each feed can have a List of replies which are also type NewsFeed. Now it is very easy for me to delete the original feed and get the updated list back. All I need to do after delete is this.
feeds = scholarEJB.findAllFeed(); //This will query the db and return updated list
But I am having problem when trying to delete replies and getting the updated list back. So here is how I delete the replies. Inside my JSF managed bean I have
//Before invoke this method, I have the value of originalFeed, and deletedFeed set.
//These original feeds are display inside a p:dataTable X, and the replies are
//displayed inside p:dataTable Y which is inside X. So when I click the delete button
//I know which feed I want to delete, and if it is the replies, I will know
//which one is its original post
public void deleteFeed(){
if(this.deletedFeed != null){
scholarEJB.deleteFeeds(this.deletedFeed);
if(this.originalFeed != null){
//Since the originalFeed is not null, this is the `replies`
//that I want to delete
scholarEJB.removeReply(this.originalFeed, this.deletedFeed);
}
feeds = scholarEJB.findAllFeed();
}
}
Then inside my EJB scholarEJB, I have
public void removeReply(NewsFeed feed, NewsFeed reply){
feed = em.merge(feed);
comment.removeReply(reply);
em.persist(comment);
}
public void deleteFeeds(NewsFeed e){
e = em.find(NewsFeed.class, e.getId());
em.remove(e);
em.getEntityManagerFactory().getCache().evict(NewsFeed.class); //Like fdreger suggested
}
When I get out, the entity (the reply) get correctly removed from the database, but inside the feeds List, reference of that reply still there. It only until I log out and log back in that the reply disappear.
What you have written is correct, requerying should work (and in factis how it’s usually done), so the problem must be somewhere else. For example if you delete the entity by any means other than the remove method, it may still be in the 2nd level cache. Or maybe the requerying does not happen at all because of some small mistake?
Update: After reading the new version of the original question (with all the new sources and clarification about Eclipselink) I made a little test, and it is – indeed – a second level cache problem. A bit strange, and possibly either a bug or an underspecified corner case. To fix it, evict comments from cache:
You could also try evicting the parent of the removed entity only (there is an overloaded version of evict).
Uhmpf. Maybe someone with more street cred (BalusC? 🙂 should change tags on this post. Turned out it has nothinh to do with JSF.