JPA @OneToOne with a shared ID - Can I do it better?

Im working with an existing circuit that Id would rather not change. A schema has a one-to-one relationship between the Person and VitalStats tables, where Person has a primary key, and VitalStats uses the same field as its primary key and its foreign key for Person, which means its value is the value of the corresponding person PK.

These records are created by external processes, and my JPA code never needs to update VitalStats. For my Id object model, such as my Person class, to contain a VitalStats element, BUT:

When i try

@Entity public class Person{ private long id; @Id public long getId(){ return id; } private VitalStats vs; @OneToOne(mappedBy = "person") public VitalStats getVs() { return vs; } } @Entity public class VitalStats{ private Person person; @OneToOne public Person getPerson() { return person; } } 

I have a problem with VitalStats not having @Id, which does not work for @Entity. \

If i try

 @Id @OneToOne public Person getPerson() { return person; } 

which solves the @Id problem but requires that Person be Serializable. OK, back to that.

I could make VitalStats @Embeddable and associate it with Person using the @ElementCollection element, but then it will need to be obtained as a collection, although I know that this is only one element. An opportunity, but also a little annoying and a bit confusing.

So, what prevents me from simply saying that the Person implements Serializable? Nothing, really, except that I like everything in my code to be there for some reason, and I don't see any logic in it, which makes my code less readable.

In the meantime, I just replaced the Person field in VitalStats with a long personId and made VitalStatss @Id, so @OneToOne now works.

All these solutions, which seem to me like simple problems, are a bit awkward, so I wonder if I am missing something or someone can at least explain to me why Person should be Serializable.

TIA

+45
java jpa one-to-one
Jul 26 '11 at 16:28
source share
2 answers

To map a one-to-one association using shared primary keys, use the @PrimaryKeyJoinColumn and @MapsId .

The relevant sections of the reference documentation for the hibernate:

PrimaryKeyJoinColumn

The PrimaryKeyJoinColumn annotation states that the primary key of the object is used as the foreign key value for the associated object.

Mapsid

MapsId annotations will ask Hibernate to copy the identifier from another related object. In sleep jargon, it is known as a foreign generator, but JPA mapping is better read and recommended.

Person.java

  @Entity public class Person { @Id @GeneratedValue(strategy=GenerationType.IDENTITY) @Column(name = "person_id") private Long id; @OneToOne(cascade = CascadeType.ALL) @PrimaryKeyJoinColumn private VitalStats vitalStats; } 

VitalStats.java

 @Entity public class VitalStats { @Id @Column(name="vitalstats_id") Long id; @MapsId @OneToOne(mappedBy = "vitalStats") @JoinColumn(name = "vitalstats_id") //same name as id @Column private Person person; private String stats; } 

Person Database Table

 CREATE TABLE person ( person_id bigint(20) NOT NULL auto_increment, name varchar(255) default NULL, PRIMARY KEY (`person_id`) ) 

VitalStats Database Table

 CREATE TABLE vitalstats ( vitalstats_id bigint(20) NOT NULL, stats varchar(255) default NULL, PRIMARY KEY (`vitalstats_id`) ) 
+65
Jul 27 '11 at 4:09
source share

In my case, this did the trick:

Parent class:

 public class User implements Serializable { private static final long serialVersionUID = 1L; /** auto generated id (primary key) */ @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @Column(unique = true, nullable = false) private Long id; /** user settings */ @OneToOne(cascade = CascadeType.ALL, mappedBy = "user") private Setting setting; } 

Child class:

 public class Setting implements Serializable { private static final long serialVersionUID = 1L; /** setting id = user id */ @Id @Column(unique = true, nullable = false) private Long id; /** user with this associated settings */ @MapsId @OneToOne @JoinColumn(name = "id") private User user; } 
+7
Apr 10 '16 at 9:44
source share



All Articles