我目前的项目是使用 JavaFX 完成的。我使用属性将(双向)视图字段绑定到 bean(使用 JFXtras 的 BeanPathAdapter)。
我选择使用 JPA 和 ObjectDB 作为模型。
这是我第一次在独立项目中使用 JPA,在这里我面临托管实体的问题。
实际上,我将托管实体绑定到视图字段,当视图字段的值发生更改时,实体会更新......数据库也会更新。
我正在尝试找到一种手动保留/合并实体的方法,以便我可以询问用户是否要保存。
这是我用来获取列表的代码:
EntityManagerFactory emf = Persistence.createEntityManagerFactory("$objectdb/data/db.odb");
EntityManager em = emf.createEntityManager();
List<XXX> entities = em.createQuery("SELECT x FROM XXX x").getResultList();
所以当我这样做的时候
entity.setName("test");
实体在数据库中更新。
我正在寻找的是实体不会自动更新。
我试过(就在getResultList之后)
em.clear();
或者
em.detach(entity);
但即使使用 CascadeType.DETACH,它也会丢失关系实例。
我也试过
em.setFlushMode(FlushModeType.COMMIT);
但它仍然会自动更新...
我还尝试克隆该对象。但是当我想合并它时,它给了我一个例外:
Attempt to reuse an existing primary key value
我想到了一个替代解决方案:使用变量作为“缓冲区”,如果用户保存,则用缓冲区填充托管 bean。但是 BeanPathAdapter 失去了意义。与手动填充视图字段和保存后手动填充bean字段相同。
你能帮我找到解决办法吗?
谢谢,
烟
编辑: 我回答我自己的问题:p
经过3个小时的研究,我找到了解决方案。
“克隆”解决方案是我引用的每个解决方案中的“最佳”解决方案,但我认为这不是最好的解决方案。
异常的原因是我用来持久化/合并我的实体的代码。我正在使用已经存在的 id 保留一个非托管实体。我还以为合并了。。。
我做了一个通用方法不会再次失败
public <T extends IEntity> T persist(T object) {
em.getTransaction().begin();
if (object.getId() == null) {
em.persist(object);
em.flush();
em.getTransaction().commit();
em.refresh(object);
}
else {
object = em.merge(object);
em.getTransaction().commit();
}
return object;
}
所以解决方案:当我必须将实体绑定到视图时,我使用 entity.clone() 以便可以将实体用作非托管实体并在需要时合并。
但是,如果您有适当的解决方案,我很感兴趣:)
再次感谢