Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Hibernate foreign key as part of primary key


I have to work with hibernate and not very sure how solve this problem, I've 2 table with a 1..n relationship like this:

-------
TABLE_A
-------
first_id (pk)
second_id (pk)
[other fields]

-------
TABLE_B
-------
first_id (pk)(fk TABLE_A.first_id)
second_id (pk)(fk TABLE_A.second_id)
third_id (pk)
[other fields]

How can I manage this with Hibernate???

I don't have idea how to manage the primary key for the second table...

like image 488
rascio Avatar asked Aug 22 '11 11:08

rascio


People also ask

Can we use foreign key as a primary key?

Foreign keys are almost always "Allow Duplicates," which would make them unsuitable as Primary Keys. Instead, find a field that uniquely identifies each record in the table, or add a new field (either an auto-incrementing integer or a GUID) to act as the primary key.

How do you make a foreign key a primary key in Hibernate?

Use @PrimaryKeyJoinColumn and @PrimaryKeyJoinColumns annotations. From Hibernate manual: The @PrimaryKeyJoinColumn annotation does say that the primary key of the entity is used as the foreign key value to the associated entity.

Can a key be primary and foreign at the same time?

A Foreign Key is used for referential integrity, to make sure that a value exists in another table. The Foreign key needs to reference the primary key in another table. If you want to have a foreign key that is also unique, you could make a FK constraint and add a unique index/constraint to that same field.


1 Answers

There is an example which is completely similar to your case in the Hibernate reference documentation. Just before this example, you'll find the explanations. Here's the example, which matches your problem (User is table A, and Customer is table B):

@Entity
class Customer {
   @EmbeddedId CustomerId id;
   boolean preferredCustomer;

   @MapsId("userId")
   @JoinColumns({
      @JoinColumn(name="userfirstname_fk", referencedColumnName="firstName"),
      @JoinColumn(name="userlastname_fk", referencedColumnName="lastName")
   })
   @OneToOne User user;
}

@Embeddable
class CustomerId implements Serializable {
   UserId userId;
   String customerNumber;

   //implements equals and hashCode
}

@Entity 
class User {
   @EmbeddedId UserId id;
   Integer age;
}

@Embeddable
class UserId implements Serializable {
   String firstName;
   String lastName;

   //implements equals and hashCode
}

Note: it would be much much simpler of you had a surrogate identifier for those two tables. Unless you're forced to deal with a legacy schema, do yourself a favor and use surrogate keys.

like image 66
JB Nizet Avatar answered Oct 05 '22 00:10

JB Nizet