如何在删除该列表的项目后更新列表

我需要花一点时间解释一下,所以请留下来。 我有表NewsFeed与自己有OneToMany关系。

 @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 replies = new ArrayList(); public void addReply(NewsFeed reply){ replies.add(reply); reply.setReplyTo(this); } public void removeReply(NewsFeed reply){ replies.remove(reply); } } 

所以你可以这样想。 每个Feed都有一个回复List ,这些回复也是NewsFeed类型。 现在,我很容易删除原始Feed并获取更新后的列表。 删除后我需要做的就是这个。

 feeds = scholarEJB.findAllFeed(); //This will query the db and return updated list 

但是在尝试删除replies并获取更新后的列表时遇到问题。 所以这是我删除replies 。 在我的JSF托管bean里面

 //Before invoke this method, I have the value of originalFeed, and deletedFeed set. //These original feeds are display inside ap: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(); } } 

然后在我的EJB学者EJB中,我有

 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 } 

当我离开时,实体(回复)被正确地从数据库中删除,但在feeds列表中,仍然存在该reply引用。 只有在我退出并重新登录之后,回复才会消失。

你写的是正确的,requerying应该工作(事实上它通常是如何做的),所以问题必须在其他地方。 例如,如果您通过除remove方法之外的任何方式删除实体,它仍可能位于二级缓存中。 或者可能因为一些小错误而没有发生重新征服?


更新 :在阅读原始问题的新版本(包含所有新的来源和关于Eclipselink的说明)后,我做了一个小测试,它确实是 – 二级缓存问题。 有点奇怪,可能是一个bug或一个未指定的角落案例。 要解决此问题,请从缓存中删除注释:

 // this goes after em.remove(e) em.getEntityManagerFactory().getCache().evict(Comment.class); 

您也可以尝试驱逐已删除实体的父级(有一个重载版本的evict)。

Uhmpf。 也许有更多街头信誉的人(BalusC?:-)应该在这篇文章中更改标签。 原来它与JSF没什么关系。

删除对象时,必须先删除对该对象的所有引用,然后才能删除它。 如果不这样做,则可以在持久性上下文或二级缓存中获取约束错误或过时数据。

删除Feed时,首先将其从回复中删除。