两个实体之间的JPA OneToOne和ManyToMany
我之前问过一个问题,但是我觉得还不够清楚,我会详细说明代码。
我有一个教师实体和部门实体
许多教师属于一个部门和
一个部门有一名教师领导该部门。
这是我实现它的方式。
@Entity public class Teacher extends Model { @Required public String surname; @Required public String othernames; ... @OneToOne(mappedBy = "deptHead") public Department headedBy = new Department(); @ManyToOne(cascade=CascadeType.ALL) public Department dept = new Department(); ... }
和部门实体
@Entity public class Department extends Model { @Required public String deptName; @OneToMany(mappedBy="dept") public List teachers = new ArrayList(); @OneToOne public Teacher deptHead = new Teacher(); ... }
我收到以下错误
@6c4nj8nmg Internal Server Error (500) for request GET / JPA error A JPA error occurred (Unable to build EntityManagerFactory): could not instantiate test objectmodels.Department play.exceptions.JPAException: Unable to build EntityManagerFactory at play.db.jpa.JPAPlugin.onApplicationStart(JPAPlugin.java:269) at play.plugins.PluginCollection.onApplicationStart(PluginCollection.java:525) at play.Play.start(Play.java:526) at play.Play.detectChanges(Play.java:630) at play.Invoker$Invocation.init(Invoker.java:198) at Invocation.HTTP Request(Play!) Caused by: org.hibernate.InstantiationException: could not instantiate test objectmodels.Department at org.hibernate.engine.UnsavedValueFactory.instantiate(UnsavedValueFactory.java:48) at org.hibernate.engine.UnsavedValueFactory.getUnsavedIdentifierValue(UnsavedValueFactory.java:67) at org.hibernate.tuple.PropertyFactory.buildIdentifierProperty(PropertyFactory.java:67) at org.hibernate.tuple.entity.EntityMetamodel.(EntityMetamodel.java:135) at org.hibernate.persister.entity.AbstractEntityPersister.(AbstractEntityPersister.java:485) at org.hibernate.persister.entity.SingleTableEntityPersister.(SingleTableEntityPersister.java:133) at org.hibernate.persister.PersisterFactory.createClassPersister(PersisterFactory.java:84) at org.hibernate.impl.SessionFactoryImpl.(SessionFactoryImpl.java:286) at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1872) at org.hibernate.ejb.Ejb3Configuration.buildEntityManagerFactory(Ejb3Configuration.java:906) at play.db.jpa.JPAPlugin.onApplicationStart(JPAPlugin.java:267) ... 5 more Caused by: java.lang.reflect.InvocationTargetException at org.hibernate.engine.UnsavedValueFactory.instantiate(UnsavedValueFactory.java:45) ... 15 more Caused by: java.lang.StackOverflowError at java.lang.Class.searchMethods(Unknown Source) at java.lang.Class.getMethod0(Unknown Source) at java.lang.Class.getMethod(Unknown Source) at play.classloading.enhancers.PropertiesEnhancer$FieldAccessor.invokeWriteProperty(PropertiesEnhancer.java:268) at models.Department.(Department.java:23) at models.Teacher.(Teacher.java:47) at models.Department.(Department.java:26) ...
需要帮助这些
这不是JPA问题,而是由Teacher
/ Department
递归实例化引起的。
当您创建或要求JPA创建Teacher
实例时, Teacher
尝试将实例化Teacher
的Department
实例化为无穷大。
因此,您在堆栈跟踪的末尾附近看到StackOverflowError
错误。
从类定义中删除= new Teacher()
和= new Department()
表达式; 在创建它们时依赖并使用适当的setter方法。
我删除了教师和部门之间的@oneToOne关系并创建了一个名为DepartmentHeads的新实体,现在一切正常。
这是结果。
@Entity public class Teacher extends Model { @Required public String surname; @Required public String othernames; ... @ManyToOne(cascade=CascadeType.ALL) public Department dept = new Department(); ... } @Entity public class Department extends Model { @Required public String deptName; @OneToMany(mappedBy="dept") public List teachers = new ArrayList (); ... } @Entity public class DepartmentHead extends Model{ @OneToOne public Teacher teacher = new Teacher(); @OneToOne public Department dept = new Department(); }
现在一切都很好。