我们的java应用程序正在使用Toplink JPA将数据访问层连接到我们的SQL Server 2008数据库。
我们可以查询数据库并获得我们的结果,没有任何问题。问题是,如果我们尝试更改返回的实体,一旦调用setter,它就会持久存储到数据库中。
Query rQuery = em.createNamedQuery("Region.findAll");
Region r= rQuery.getResultList();
r.setActive(active);
从我们在JPA上阅读的内容看来,在调用persist / merge / flush之前,它似乎不应该将更改发送到数据库。这是我们希望拥有的行为。我们希望能够进行所有更改,然后立即发送所有更改。如果我们一次发送一个并且我们收到错误,我们最终会得到部分更新的记录。
我已经尝试将实体管理器刷新模式设置为提交,以便在持久化之前强制它等待提交调用,并且它没有任何区别。
em.setFlushMode(FlushModeType.COMMIT);
我还尝试在调用setter之前分离返回的实体,但它会引发异常。
java.lang.AbstractMethodError:oracle.toplink.essentials.internal.ejb.cmp3.EntityManagerImpl.detach(Ljava / lang / Object;)
这是我们第一次使用Toplink JPA,我们不知道还有什么可以尝试。 如果有人对如何解决这个问题有任何其他建议,我真的很感激。
答案 0 :(得分:2)
如果您对实体的更新代码是在标记有事务的方法中完成的,那么在该方法结束时,将提交更改,因为事务必须在关闭之前提交任何更改。
如果实体已分离,则使用合并,您对该实体进行了一些更改,并且需要再次重新附加它并将更新合并到数据库中。
解决方案是使用事务属性“Require_new”以不同方法查询数据,并将结果集传递给使用事务属性“required”或“mandatory”执行更新的方法。