One-to-One JPA Hibernate Communication

I have a one-to-one relationship, but hibernatetool complains when creating the schema. Here is an example that shows the problem:

@Entity public class Person { @Id public int id; @OneToOne public OtherInfo otherInfo; rest of attributes ... } 

A person has a one-to-one relationship with OtherInfo:

 @Entity public class OtherInfo { @Id @OneToOne(mappedBy="otherInfo") public Person person; rest of attributes ... } 

The person belongs to the OtherInfo side. OtherInfo is its own side, so a person uses mappedBy to specify the name of the "otherInfo" attribute in Person.

I get the following error when using hibernatetool to create a 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 doing something wrong or is it a Hibernate error?

+58
java hibernate jpa
Apr 24 '09 at 21:48
source share
7 answers

JPA does not allow @Id annotation to display OneToOne or ManyToOne. What you are trying to do is a one-to-one association of entities with a common primary key . The simplest case is unidirectional unidirectional with a shared key:

 @Entity public class Person { @Id private int id; @OneToOne @PrimaryKeyJoinColumn private OtherInfo otherInfo; rest of attributes ... } 

The main problem is that JPA does not support support for generating a shared primary key in an InfoInfo object. The classic Java Saving book with Hibernate by Bauer and King provides the following solution to the problem using the 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 .

+84
Apr 25 '09 at 13:45
source share

This should also work using JPA 2.0 @MapsId annotations instead of the Hibernate 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 ... } 

See the Hibernate 4.1 documentation in section 5.1.2.2.7 for more on this.

+22
Aug 27 2018-12-12T00:
source share

You just need to add the @JoinColumn(name="column_name") relation to the Host Entity object. column_name is the name of the database column in the person table.

 @Entity public class Person { @Id public int id; @OneToOne @JoinColumn(name="other_info") public OtherInfo otherInfo; rest of attributes ... } 

A person has a one-to-one relationship with OtherInfo: mappedBy = "var_name" var_name is the name of the variable for another object in the Person class.

 @Entity public class OtherInfo { @Id @OneToOne(mappedBy="otherInfo") public Person person; rest of attributes ... } 
+10
Oct 10
source share

I think you still need the primary key property in the OtherInfo class.

 @Entity public class OtherInfo { @Id public int id; @OneToOne(mappedBy="otherInfo") public Person person; rest of attributes ... } 

In addition, you may need to add the @PrimaryKeyJoinColumn annotation to the other side of the display. I know that Hibernate uses this by default. But then I did not use JPA annotations, which, as you think, require you to specify as an association wokrs.

+4
Apr 25 '09 at 6:12
source share

I have a better way to do this:

 @Entity public class Person { @OneToOne(cascade={javax.persistence.CascadeType.ALL}) @JoinColumn(name = "`Id_OtherInfo`") public OtherInfo getOtherInfo() { return otherInfo; } } 

What all

+2
May 19 '11 at 16:24
source share

I'm not sure that you can use relationships like Id / PrimaryKey in sleep mode.

+1
Apr 24 '09 at 21:55
source share

try it

 @Entity @Table(name="tblperson") public class Person { public int id; public OtherInfo otherInfo; @Id //Here Id is autogenerated @Column(name="id") @GeneratedValue(strategy=GenerationType.AUTO) public int getId() { return id; } public void setId(int id) { this.id = id; } @OneToOne(cascade = CascadeType.ALL,targetEntity=OtherInfo.class) @JoinColumn(name="otherInfo_id") //there should be a column otherInfo_id in Person public OtherInfo getOtherInfo() { return otherInfo; } public void setOtherInfo(OtherInfo otherInfo) { this.otherInfo= otherInfo; } rest of attributes ... } @Entity @Table(name="tblotherInfo") public class OtherInfo { private int id; private Person person; @Id @Column(name="id") @GeneratedValue(strategy=GenerationType.AUTO) public Long getId() { return id; } public void setId(Long id) { this.id = id; } @OneToOne(mappedBy="OtherInfo",targetEntity=Person.class) public College getPerson() { return person; } public void setPerson(Person person) { this.person = person; } rest of attributes ... } 
+1
Apr 25 '09 at 5:40
source share



All Articles