我为每个实体类型创建了一个存储库类(一个处理所有jpa方法的类),它拥有自己的entitymanagerfactory。 现在我在多对多的关系中遇到了以下错误:
ValidationException
[junit][EclipseLink-7251] Exception Description: The attribute [ID] of class [Person] is mapped to a primary key column in the database. Updates are not allowed.
这种错误在调试时通常不再发生,并且看起来并不一致,这使我相信它可能是管理者之间的同步问题。 (Pk由jpa处理 - @Id @GeneratedValue - 我从未改变过,我确实使用了级联合并)
我目前的假设是正确的,即拥有多个entitymanagerfactories是一个坏主意(可能与我的问题有关)?
答案 0 :(得分:1)
EntityManagerFactory表示一个持久单元,或者换句话说,一个数据源。如果您没有多个数据源,那么您就不应该创建多重EMF。您可以创建多个EntityManagers(您可以将其视为' connections'到数据库)。
您可以像这样创建EMF -
EntityManagerFactory emf = Persistence.createEntityManagerFactory(
"objectdb://localhost/myDbFile.odb;user=admin;password=admin")
或
EntityManagerFactory emf =
Persistence.createEntityManagerFactory("myDbFile.odb");
你可以像这样创建EntityManager -
EntityManager em = emf.createEntityManager();
来自Javadoc - http://docs.oracle.com/javaee/7/api/javax/persistence/EntityManagerFactory.html
用于与持久性单元的实体管理器工厂交互的接口。当应用程序完成使用实体管理器工厂和/或应用程序关闭时,应用程序应关闭实体管理器工厂。一旦EntityManagerFactory关闭,其所有实体管理器都被认为处于关闭状态。
添加更多内容,您可能还需要像这样创建的事务 -
try {
em.getTransaction().begin();
// Operations that modify the database should come here.
em.getTransaction().commit();
}
finally {
if (em.getTransaction().isActive())
em.getTransaction().rollback();
}
答案 1 :(得分:0)
我得出的结论是,不同的EMF实际上导致了单独的持久化上下文,这导致了像validationException这样的问题。
(我认为这发生在同一实体的2个不同实例在2个不同的上下文中进行管理,其中一个实例改变了它的状态,虽然我不确定)
像这样测试:
备注:
(junit测试方法的相关部分)
OrderBill cheapOrder = new OrderBill(5, LocalDate.now());
weekRep.addWeek(cheapOrder.getOrderWeek());
//because of the cascade, both the cheapOrder and the week or now persisted in the DB and managed by weekRep
OrderBill dbOrder = orderRep.updateOrder(cheapOrder);
boolean t2 = weekRep.isManaged(cheapOrder); //true
boolean t3 = orderRep.isManaged(cheapOrder); //false
//It's because this returns false I assume both persistence contexts are different
boolean t4 = orderRep.isManaged(dbOrder); //true
//If i now use "cheapOrder" to change the order i get the error
//If i now use "dbOrder" to change the order, db gets updated as expected