【问题标题】:Bidirectional OneToMany assocation between sub and superclass not working (JPA with Hibernate 3.6.7)子类和超类之间的双向 OneToMany 关联不起作用(JPA with Hibernate 3.6.7)
【发布时间】:2011-10-27 21:26:12
【问题描述】:

我有两个班级,员工和经理。 Manager 扩展了 Employee,因为它是一种员工。 Employee 有一个 Manager 的实例,它代表一个员工有一个经理的想法。相反,经理有一组员工。有两个表,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 和 getter):

@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 在 sun.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException(UnsafeFieldAccessorImpl.java:164) 在 sun.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException (UnsafeFieldAccessorImpl.java:168) 在 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 更多

我是不是写错了代码,或者 hibernate 根本无法处理这种情况?如有任何帮助,我将不胜感激。

【问题讨论】:

    标签: hibernate jpa parent bidirectional


    【解决方案1】:

    经理中的EMPLOYEEID 列不应该存在。 @PrimaryKeyJoinColumn 表示主键也是连接列。所以,MANAGER 中的ID 列既是EMPLOYEE 的主键也是外键。

    而且注解当然要改成@PrimaryKeyJoinColumn(name="ID")(或者必须去掉,因为默认是使用与父表中相同的列名)

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

    【讨论】:

    • 非常感谢你,你是个天才。我按照您的指示修好了,现在可以正常使用了!
    猜你喜欢
    • 1970-01-01
    • 2013-06-17
    • 2017-03-10
    • 2012-12-17
    • 1970-01-01
    • 1970-01-01
    • 2017-05-22
    • 2014-05-31
    • 1970-01-01
    相关资源
    最近更新 更多