sub和superclass之间的双向OneToMany关联不起作用(JPA with Hibernate 3.6.7)

时间:2011-10-27 21:26:13

标签: hibernate jpa parent bidirectional

我有两个班,员工和经理。经理扩展了员工,因为它是一种员工。员工有一个经理实例,代表员工拥有一名经理的想法。相反,经理有一套员工。有两个表,EMPLOYEE和MANAGER:

table EMPLOYEE
  long ID
  varchar NAME
  long MANAGERID

table MANAGER
  long ID
  long EMPLOYEEID //a join on this field enables inheritance

这些课程如下:

Employee.java(为简洁省略了setter和getters):

@Entity
@Inheritance(strategy = InheritanceType.JOINED)
@Table(name = "EMPLOYEE", schema = "TEST01")
public class Employee extends hata.util.Entity implements java.io.Serializable {

    @Id
    @GeneratedValue(strategy=GenerationType.IDENTITY)
    @Column(name = "ID", unique = true, nullable = false)   
    protected Long id;

    @ManyToOne(fetch = FetchType.EAGER)
    @JoinColumn(name = "MANAGERID")
    protected Manager manager;

    @Column(name = "FIRSTNAME", nullable = false, length = 50)
    protected String firstname;

Manager.java

@Entity
@PrimaryKeyJoinColumn(name="EMPLOYEEID")
@Table(name = "MANAGER", schema = "TEST01")
public class Manager extends Employee implements java.io.Serializable {

    @OneToMany(fetch = FetchType.LAZY, mappedBy = "manager")
    private Set<Employee> employees = new HashSet<Employee>(0);

我已经填满了几个员工的桌子,所有这些员工都有同一个经理,除了一个员工 - 经理人。他本人没有经理。 (如果你正确地关注我,那么很明显我在manager表中有1行,并且EMPLOYEEID引用回EMPLOYEE表中的一行,因为它的MANAGERID为null)。

所以,这个设置对我来说是正确的,但是当我尝试使用以下方法查询所有Employee对象时

Query q = em.createQuery("select em from Employee em");
result = (List<Employee>) q.getResultList();

我得到一个讨厌的堆栈跟踪:

引起:org.hibernate.PropertyAccessException:无法通过hata.staff.entity.Employee.manager的反射设置器设置字段值     在org.hibernate.property.DirectPropertyAccessor $ DirectSetter.set(DirectPropertyAccessor.java:151)     在org.hibernate.tuple.entity.AbstractEntityTuplizer.setPropertyValues(AbstractEntityTuplizer.java:586)     在org.hibernate.tuple.entity.PojoEntityTuplizer.setPropertyValues(PojoEntityTuplizer.java:231)     在org.hibernate.persister.entity.AbstractEntityPersister.setPropertyValues(AbstractEntityPersister.java:3824)     在org.hibernate.engine.TwoPhaseLoad.initializeEntity(TwoPhaseLoad.java:153)     在org.hibernate.loader.Loader.initializeEntitiesAndCollections(Loader.java:898)     在org.hibernate.loader.Loader.doQuery(Loader.java:773)     在org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:270)     在org.hibernate.loader.Loader.doList(Loader.java:2294)     在org.hibernate.loader.Loader.listIgnoreQueryCache(Loader.java:2172)     在org.hibernate.loader.Loader.list(Loader.java:2167)     在org.hibernate.loader.hql.QueryLoader.list(QueryLoader.java:448)     在org.hibernate.hql.ast.QueryTranslatorImpl.list(QueryTranslatorImpl.java:363)     在org.hibernate.engine.query.HQLQueryPlan.performList(HQLQueryPlan.java:196)     在org.hibernate.impl.SessionImpl.list(SessionImpl.java:1258)     在org.hibernate.impl.QueryImpl.list(QueryImpl.java:102)     在org.hibernate.ejb.QueryImpl.getResultList(QueryImpl.java:236)     ......还有108个 引起:java.lang.IllegalArgumentException:无法将hata.staff.entity.Manager字段hata.staff.entity.Employee.manager设置为hata.staff.entity.Employee     at sun.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException(UnsafeFieldAccessorImpl.java:164)     at sun.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException(UnsafeFieldAccessorImpl.java:168)     at sun.reflect.UnsafeObjectFieldAccessorImpl.set(UnsafeObjectFieldAccessorImpl.java:81)     在java.lang.reflect.Field.set(Field.java:680)     在org.hibernate.property.DirectPropertyAccessor $ DirectSetter.set(DirectPropertyAccessor.java:139)     ......还有124个

我编码错了,还是可以暂停处理这种情况?我很感激你的帮助。

1 个答案:

答案 0 :(得分:0)

经理中的EMPLOYEEID列不应该在那里。 @PrimaryKeyJoinColumn表示主键也是连接列。因此,ID中的MANAGER列既是主键,也是EMPLOYEE的外键。

并且注释当然应该更改为@PrimaryKeyJoinColumn(name="ID")(或者必须将其删除,因为默认情况下使用与父表中相同的列名称)

请参阅http://download.oracle.com/javaee/6/api/javax/persistence/PrimaryKeyJoinColumn.html