У меня есть следующий простой дизайн:
Действительный XHTML http://www.kawoolutions.com/media/persons-roles-reduced.png
Это в основном обходной путь для несвязанного наследования, который не поддерживается JPA. Персоны могут существовать самостоятельно, но при желании для завершения логики может существовать один игрок, один тренер или оба объекта.
Вот довольно простые для понимания JPA 2.0 отображения (обратите внимание на связи @Id forward):
@Entity
@Table(name = "Persons")
public class Person implements Serializable
{
@Id
@Column(name = "id")
private Integer id;
@Column(name = "first_name")
private String firstName;
@Column(name = "last_name")
private String lastName;
@OneToOne(mappedBy = "person")
private Coach coach = null;
@OneToOne(mappedBy = "person")
private Player player = null;
...
}
@Entity
@Table(name = "Players")
public class Player implements Serializable
{
@Column(name = "registration_nbr")
private String registrationNbr = null;
@Id
@OneToOne
@JoinColumn(name = "id")
private Person person = null;
...
}
@Entity
@Table(name = "Coaches")
public class Coach implements Serializable
{
@Column(name = "license_nbr")
private String licenseNbr = null;
@Id
@OneToOne
@JoinColumn(name = "id")
private Person person = null;
...
}
Классы сущностей Player и Coach практически идентичны.
Проблема здесь в двух двунаправленных ассоциациях (mappedBy). Эти сопоставления прекрасно работают с EclipseLink, но Hibernate почему-то сходит с ума с AnnotationException:
Exception in thread "main" javax.persistence.PersistenceException: [PersistenceUnit: persons] Unable to configure EntityManagerFactory
at org.hibernate.ejb.Ejb3Configuration.configure(Ejb3Configuration.java:374)
at org.hibernate.ejb.HibernatePersistence.createEntityManagerFactory(HibernatePersistence.java:56)
at javax.persistence.Persistence.createEntityManagerFactory(Persistence.java:48)
at javax.persistence.Persistence.createEntityManagerFactory(Persistence.java:32)
at tld.persons.Main.main(Main.java:32)
Caused by: org.hibernate.AnnotationException: Unknown mappedBy in: tld.persons.model.Person.coach, referenced property unknown: tld.persons.model.Coach.person
at org.hibernate.cfg.OneToOneSecondPass.doSecondPass(OneToOneSecondPass.java:159)
at org.hibernate.cfg.Configuration.originalSecondPassCompile(Configuration.java:1686)
at org.hibernate.cfg.Configuration.secondPassCompile(Configuration.java:1393)
at org.hibernate.cfg.Configuration.buildMappings(Configuration.java:1345)
at org.hibernate.ejb.Ejb3Configuration.buildMappings(Ejb3Configuration.java:1477)
at org.hibernate.ejb.EventListenerConfigurator.configure(EventListenerConfigurator.java:193)
at org.hibernate.ejb.Ejb3Configuration.configure(Ejb3Configuration.java:1096)
at org.hibernate.ejb.Ejb3Configuration.configure(Ejb3Configuration.java:278)
at org.hibernate.ejb.Ejb3Configuration.configure(Ejb3Configuration.java:362)
... 4 more
При переходе на сопоставления старой школы JPA 1.0 все снова работает нормально. Hibernate почему-то, похоже, имеет проблемы с приведенными выше сопоставлениями.
Я просмотрел множество других сообщений о проблемах, на самом деле форум на hibernate.org заполнен похожими нерешенными проблемами, но я не смог найти никаких подсказок относительно того, почему это вызывает исключение.
Мне кажется, это ошибка Hibernate. Кто-нибудь может это подтвердить? (Обратите внимание, что я использую Hibernate 3.6)