Двунаправленная связь OneToMany между подчиненным и суперклассом не работает (JPA с Hibernate 3.6.7) - PullRequest
1 голос
/ 28 октября 2011

У меня есть два класса, сотрудник и менеджер.Менеджер расширяет Сотрудника, так как это тип сотрудника.У сотрудника есть экземпляр менеджера, который представляет идею, когда у сотрудника есть один менеджер.Наоборот, менеджер имеет набор сотрудников.Существует две таблицы: 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 (сеттеры и геттеры опущены для краткости):

@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);

Я заполнил таблицы несколькими сотрудниками, и у всех этих сотрудников один и тот же менеджер, за исключением одного сотрудника, который является менеджером.У него самого нет менеджера.(Если вы правильно следите за мной, то должно быть очевидно, что у меня есть 1 строка в таблице менеджера, а EMPLOYEEID ссылается на строку в таблице EMPLOYEE, которая имеет значение NULL, поскольку оно равно MANAGERID).

Таким образом, эта установка выглядела правильно для меня, однако, когда я попытался запросить все объекты 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.jers.serte.Entorg.hibernate.engine.TwoPhaseLoad.initializeEntity (TwoPhaseLoad.java:153) в илиg.hibernate.loader.Loader.initializeEntitiesAndCollections (Loader.java:898) в org.hibernate.loader.Loader.doQuery (Loader.java:773) в org.hibernate.loader.Loader.doQueryAndInitializeNonLazyader (Loader)в 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.queryPHQ.executeList (HQLQueryPlan.java:196) в org.hibernate.impl.SessionImpl.list (SessionImpl.java:1258) в org.hibernate.impl.QueryImpl.list (QueryImpl.java:102) в org.hibernate.ejmplQuery.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) at org.hibernate.property.DirectPropertyAccessor $ DirectSetter.set (DirectPropertyAccessor.java:139) ... еще 124

Я кодировал это неправильно или могуhibernate просто не справиться с этим сценарием?Буду признателен за любую помощь.

1 Ответ

0 голосов
/ 28 октября 2011

Не должно быть столбца EMPLOYEEID в менеджере. @PrimaryKeyJoinColumn означает, что первичный ключ также является столбцом соединения. Таким образом, столбец ID в MANAGER является и первичным ключом, и внешним ключом для EMPLOYEE.

И аннотацию, конечно, следует изменить на @PrimaryKeyJoinColumn(name="ID") (или ее необходимо удалить, поскольку по умолчанию используется то же имя столбца, что и в родительской таблице)

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...