2013-07-25 40 views
0

我正在使用JPA(EclipseLink 2.5)进行持久化。我的网络应用程序包含AJAX页面更新。保存帖子后,发布的内容不会刷新浏览器。该帖子使用OneToMany关系具有与其关联的标签。这些标签应该在保存后显示出来。但是,由于缓存已启用,我无法获取标签。如何在保留后刷新缓存?

这里是我的代码:

@TransactionAttribute(TransactionAttributeType.REQUIRED) 
public Sqask save(AskTag tags) { 
    try { 
     Sqask ask = saveAsk(tags); 
     return ask; 
    } catch (Exception e) { 
     context.setRollbackOnly(); 
     return null; 
    } 
} 

public Sqask saveAsk(AskTag tags) { 
     Sqask ask = new Sqask(); 
     ask.setCreator(tags.getAskedBy()); 
     em.persist(ask); 
     em.flush(); 
     saveTags(tags, ask); 
     return ask; 
    } 

public void saveTags(AskTag tags, Sqask ask) { 
     if (!tags.getNask().isEmpty()) { 
      NAsk nask = new NAsk(); 
      NAskPK naskPK = new NAskPK(); 
      naskPK.setAsk(ask.getId()); 
      naskPK.setNoun(tags.getNask()); 
      naskPK.setCreator(tags.getAskedBy().getGuid()); 
      nask.setNAskPK(naskPK); 
      nask.setAsk(ask); 
      nask.setCreator(tags.getAskedBy()); 
      em.persist(nask); 
     } 

     if (!tags.getVask().isEmpty()) { 
      VAsk vask = new VAsk(); 
      VAskPK vaskPK = new VAskPK(); 
      vaskPK.setAsk(ask.getId()); 
      vaskPK.setVerb(tags.getVask()); 
      vaskPK.setCreator(tags.getAskedBy().getGuid()); 
      vask.setVAskPK(vaskPK); 
      vask.setAsk(ask); 
      vask.setCreator(tags.getAskedBy()); 
      em.persist(vask); 
     } 

     if (!tags.getForask().isEmpty()) { 
      PAsk forask = new PAsk(); 
      PAskPK foraskPK = new PAskPK(); 
      foraskPK.setAsk(ask.getId()); 
      foraskPK.setPrep(tags.getForask()); 
      foraskPK.setCreator(tags.getAskedBy().getGuid()); 
      forask.setPAskPK(foraskPK); 
      forask.setAsk(ask); 
      forask.setCreator(tags.getAskedBy()); 
      em.persist(forask); 
     } 

     if (!tags.getAboutask().isEmpty()) { 
      PAsk aboutask = new PAsk(); 
      PAskPK aboutaskPK = new PAskPK(); 
      aboutaskPK.setAsk(ask.getId()); 
      aboutaskPK.setPrep(tags.getAboutask()); 
      aboutaskPK.setCreator(tags.getAskedBy().getGuid()); 
      aboutask.setPAskPK(aboutaskPK); 
      aboutask.setAsk(ask); 
      aboutask.setCreator(tags.getAskedBy()); 
      em.persist(aboutask); 
     } 

     em.getEntityManagerFactory().getCache().evict(Sqask.class, ask.getId()); 
     em.merge(ask); 
} 

我怎样才能得到的东西的工作?如何刷新与其所有关联实体的实体?谢谢。

+0

我不确定驱逐,然后合并询问实例时,前面的代码似乎根本没有修改问题实例的点。假设saveTags在同一个事务中,ask仍然被管理,所以没有任何合理的原因,并且事务没有提交,所以没有任何东西可以从共享缓存中驱逐出去。我的猜测是你正在设置双向关系的一方,并且只需要在询问实体上设置关系。 Em.flush(); em.refresh(ASK);也会起作用,但会导致不必要的数据库命中。 – Chris

回答

0

如果我正确理解你的问题,也许这可以帮助你 - 请在返回之前注意em.refresh呼叫。这确保了所有OneToOne和OneToMany联接都会刷新,即使您只保存相关记录的ID。

public T create(T entity) { 
    em.persist(entity); 
    em.flush(); 
    em.refresh(entity); // this could be important 
    return entity; 
} 
+0

是的,这是我解决我的问题。为什么我需要添加flush();刷新之前? – Yangrui

+0

Flush确保将更改写入DB(交易已完成),如果您拥有@JoinColumn字段,则需要刷新。例如:您可以拥有一个实体车辆,该车辆具有字段 - manufacturerId和制造商(这是制造商类别 - 实际上是一个对象)。保存记录(提供制造商的ID)以及更新后 - “制造商”对象将可供您使用。我希望我在这里有意义;) – daxur

+0

非常感谢!这非常有帮助 – Yangrui

0

它也可能是一个AJAX缓存问题。请你能分享一些AJAX调用的代码片段吗?原因是,如果您使用JavaScript进行AJAX,您最终可能会遇到缓存问题。只是检查它。如果你认为这个问题是JPA缓存,围绕实体管理工作平齐并刷新就能解决问题

+0

您好我正在使用JSF 2.2 for ajax。我试过并发现后台没有更新。 – Yangrui

+0

所以你找出了这个问题? – spukar

+1

是的,我用flush()来更新列表 – Yangrui

0

我不是很确定是否将工作或没有,但请尽量将 在你的代码是否存在后端问题。

em.merge(ask); 
ask.getId(); 

em.merge(ask); 
ask.getId(); 
ask.getCollection1ofAsk().size(); 
ask.getCollection2OfAsk().size(); 
..... 
0

加入em.flush后()em.refresh(问)之前,代码工作作为我的本意。它提取与实体询问相关的列表。谁能解释为什么?非常感谢