Hibernate: AnnotationException: Unknown mappedBy in ... referenced property unknown on reverse (mappedBy), bi-directional @OneToOne associations
I have the following simple design:
(source: kawoolutions.com)That's basically a workaround for non-disjoint inheritance which JPA doesn't support. Persons can exist by their own, but there can optionally be a single player entity, a single coach entity, or both entities to complete the logic.
Here are the rather easy-to-understand JPA 2.0 mappings (note the @Id forward associations):
@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")
priv开发者_StackOverflowate 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;
...
}
The Player and Coach entity classes are almost identical.
The problem here are the two bi-directional associations (mappedBy). These mappings work perfectly with EclipseLink, but Hibernate somehow freaks out with an 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
When switching to old-school JPA 1.0 mappings all runs fine again. Hibernate somehow seems to have problems with the above mappings.
I've looked at soo many other problem reports, in fact the forum at hibernate.org is filled with similar unsolved problems, but I couldn't find any clues as to why this throws an exception.
To me it appears to be a Hibernate bug. Can anybody confirm this? (Note I'm using Hibernate 3.6)
The issue can be encountered if we forget to declare entity class in persistence.xml.
Awful bug. As I said EclipseLink has no problems with it. View the bug report here (and vote for it):
http://opensource.atlassian.com/projects/hibernate/browse/HHH-5695
make sure the reference property name and setter getter methods name in annotation class should be same For Example: i have two classess Cat and Dog having one to one relationship
in Cat class
class Cat {
private Dog doggy;
@OneToOne(fetch = FetchType.LAZY)
@PrimaryKeyJoinColumn
public Dog getdoggy() {
return this.doggy;
}
public void setdoggy(Dog doggy) {
this.doggy= doggy;
}
}
in Dog class
class Dog {
private Cat cat;
@OneToOne(fetch = FetchType.LAZY, mappedBy = "doggy")
public Cat getCat() {
return this.cat;
}
public void setCat(Cat cat) {
this.cat= cat;
}
}
精彩评论