如何在Java SE应用程序中管理两个持久性单元

时间:2012-07-11 07:13:59

标签: java jpa eclipselink

我们开发了一个适用于两个持久性单元的应用程序。应用程序从一个PU1中检索实体并在循环中处理它们。

在此循环中,它更新PU2的记录,最后更新PU1实体并将其标记为已处理。

它工作正常,但问题是我必须为PU1权利的每次遍历开始/提交PU2,因为我们正面临性能问题。

try{
em1.getTransaction.begin();
Query query = em1.createNamedQuery("Request.SELECT_ALL");
query.setMaxResults(1000);
List<LoaneeRefill> requests = query.getResultList();

for (Request vo : requests) {

 em2.getTransaction.begin();

 Response r =new Resopnse();
 r.setNumber(vo.getNumber);

 em2.persist(r);

 em2.getTransaction.commit();

 vo.setStatus("Y");
 em1.merge(vo);
 }


 em1.getTransaction.commit();
 }catch(Exception e){}

上述代码导致性能问题/在大量请求上花费大量时间。

我尝试过以下代码,但收到错误:

 try{
 em1.getTransaction.begin();
 em2.getTransaction.begin();

 Query query = em1.createNamedQuery("Request.SELECT_ALL");
 query.setMaxResults(1000);
 List<LoaneeRefill> requests = query.getResultList();

 for (Request vo : requests) {

 Response r =new Resopnse();
 r.setNumber(vo.getNumber);

 em2.persist(r);

 vo.setStatus("Y");
 em1.merge(vo);
 }


 em2.getTransaction.commit();
 em1.getTransaction.commit();
 }catch(Exception e){}

错误:

javax.persistence.PersistenceException: Exception [EclipseLink-7197] (Eclipse Persistence Servi
ces - 2.1.1.v20100817-r8050): org.eclipse.persistence.exceptions.ValidationException
Exception Description: Null or zero primary key encountered in unit of work clone

编辑:

如果我从PU1获得实体列表并将其分离,则有任何建议。然后处理这些请求并使用一次更新或任何其他方式更新列表。

1 个答案:

答案 0 :(得分:0)

这取决于您在数据库中生成ID的方式。如果它们是通过数据库上的自动增量生成的,那么下面的信息可能是获得更好性能的唯一选择。

如果您有其他ID系统,或者可以更改生成ID的方式,请查看here以获取有关如何使用表或序列生成ID的更多信息,以及两个系统的优点和缺陷


在for循环结束时,尝试添加...

em2.flush();

原因是JPA实际上没有将更改提交到数据库单元的提交行。因此,ID尚未设置。 (我认为它为占位符添加了一个0)当你尝试在不提交第一个项目的情况下持久保存第二个项目时,它最终会得到一个具有相同占位符id的第二个记录。

flush实际上会执行SQL以实际将记录添加到数据库并获取创建的真实ID,但是事务处于打开状态,因此您应该看到性能提升。

似乎持久性API应该足够聪明,可以同时处理多个新记录,但这不是我的经验,可能有充分的理由,但我不知道它是什么。