I have a one-to-one relationship but hibernatetool complains when generating the schema. Here's an example that shows the problem:
@Entity public class Person { @Id public int id; @OneToOne public OtherInfo otherInfo; rest of attributes ... }
Person has a one-to-one relationship with OtherInfo:
@Entity public class OtherInfo { @Id @OneToOne(mappedBy="otherInfo") public Person person; rest of attributes ... }
Person is owning side of OtherInfo. OtherInfo is the owned side so person uses mappedBy
to specify the attribute name "otherInfo" in Person.
I get the following error when using hibernatetool to generate the database schema:
org.hibernate.MappingException: Could not determine type for: Person, at table: OtherInfo, for columns: [org.hibernate.mapping.Column(person)] at org.hibernate.mapping.SimpleValue.getType(SimpleValue.java:292) at org.hibernate.mapping.SimpleValue.createIdentifierGenerator(SimpleValue.java:175) at org.hibernate.cfg.Configuration.iterateGenerators(Configuration.java:743) at org.hibernate.cfg.Configuration.generateDropSchemaScript(Configuration.java:854) at org.hibernate.tool.hbm2ddl.SchemaExport.<init>(SchemaExport.java:128) ...
Any idea why? Am I a doing something wrong or is this a Hibernate bug?
For a One-to-One relationship in JPA, each entity instance is related to a single instance of another entity. It means each row of one entity is referred to one and only one row of another entity.
Define Hibernate Mapping FileThe <many-to-one> element will be used to define the rule to establish a one-to-one relationship between EMPLOYEE and ADDRESS entities, but column attribute will be set to unique constraint and rest of the mapping file will remain as it was in case of many-to-one association.
The One-To-One mapping represents a single-valued association where an instance of one entity is associated with an instance of another entity. In this type of association one instance of source entity can be mapped atmost one instance of target entity.
Implementing With a Foreign Key in JPA. Note that we place the @OneToOne annotation on the related entity field, Address. Also, we need to place the @JoinColumn annotation to configure the name of the column in the users table that maps to the primary key in the address table.
JPA doesn't allow the @Id annotation on a OneToOne or ManyToOne mapping. What you are trying to do is one-to-one entity association with shared primary key. The simplest case is unidirectional one-to-one with shared key:
@Entity public class Person { @Id private int id; @OneToOne @PrimaryKeyJoinColumn private OtherInfo otherInfo; rest of attributes ... }
The main problem with this is that JPA provides no support for shared primary key generation in OtherInfo entity. The classic book Java Persistence with Hibernate by Bauer and King gives the following solution to the problem using Hibernate extension:
@Entity public class OtherInfo { @Id @GeneratedValue(generator = "customForeignGenerator") @org.hibernate.annotations.GenericGenerator( name = "customForeignGenerator", strategy = "foreign", parameters = @Parameter(name = "property", value = "person") ) private Long id; @OneToOne(mappedBy="otherInfo") @PrimaryKeyJoinColumn public Person person; rest of attributes ... }
Also, see here.
This should be working too using JPA 2.0 @MapsId annotation instead of Hibernate's GenericGenerator:
@Entity public class Person { @Id @GeneratedValue public int id; @OneToOne @PrimaryKeyJoinColumn public OtherInfo otherInfo; rest of attributes ... } @Entity public class OtherInfo { @Id public int id; @MapsId @OneToOne @JoinColumn(name="id") public Person person; rest of attributes ... }
More details on this in Hibernate 4.1 documentation under section 5.1.2.2.7.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With