我有一个相对运行的工厂MVC
方案,其中视图(JSF
)使用{EJB
通过managed bean
加载NamedQuery
中的托管实体列表在Entity
类中定义的{1}}。每个实体在视图中都是可修改的,其集合由Primefaces
组件p:accordionPanel
表示。在面板的每个选项卡中都有一个表单,允许更新相应的实体:
JSF:
<p:accordionPanel id="entityAccordion" value="#{managedBean.entityList}"
var="entity" multiple="false" dynamic="true" cache="true">
托管bean:
public List<Appeal> getEntityList() {
//this loads entities from DB
return manager.getEntityList(this.parentID)
}
当用户在视图中更改表单值时,AJAX
会自动更新托管bean中的缓存实体。但是,只有通过点击表单中的提交按钮才能触发新值的传递。在第一次表单更改和提交之间,缓存的实体对象的状态与其对应的DB行不同。我需要实现将DB状态恢复到表单,以防用户改变主意并取消其更改。我不能仅通过刷新视图来实现它,因为这将使我从托管bean获取缓存对象,由于AJAX,它与视图中的相同 - 我需要先将缓存对象刷新到最后一个持久存储在数据库中,然后使用缓存对象刷新视图。
到目前为止,我已经尝试了几件事,但都没有效果:
EJB:
//this fails because it reconstructs new entity object
//but managed bean keeps binding to the old one
public void refreshEntity(Entity entity) {
//I had to do this prior to refresh as without it says entity is not managed
//but it reconstructs the instance rather than refresh existing
Entity result = this.entityManager.find(Entity.class, entity.getID());
this.entityManager.refresh(result);
return result;
}
//not sure why this fails but i tried it as per JPA spec
public void clearEntity() {
this.entityManager.clear();
}
正如您在第一个尝试解决方案的注释中所看到的那样,它不起作用,因为托管bean似乎保持对旧对象的引用,而EJB刷新方法将该变量的指针更改为全新构造对象。我希望托管bean在垃圾收集旧对象之后会重新指向新对象,但它不会这样做,渲染刷新(至少我正在做的方式)是无用的。
如何将缓存的实体对象恢复到其上一个持久状态,同时保留对该对象的所有视图绑定?
提及我们在我们的应用程序中使用JPA API可能会很有用,它在后端使用Hibernate
实现。