10


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...

rascio
  • 8,968
  • 19
  • 68
  • 108

4 Answers4

20

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.

JB Nizet
  • 678,734
  • 91
  • 1,224
  • 1,255
  • But do you know if there are some problems if I change instead of put the OneToOne annotation on the Customer, put a OneToMany on the User class??? – rascio Aug 22 '11 at 13:07
  • You'll have to make it a bidirectional OneToMany/ManyToOne association. – JB Nizet Aug 22 '11 at 13:10
  • Doing so, I get `Attribute "userId" has invalid mapping in this context` inside of `CustomerId` – Rafael Eyng Sep 21 '16 at 04:16
4

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.

Tomasz Nurkiewicz
  • 334,321
  • 69
  • 703
  • 674
  • 3
    This doesn't answer the OP's question: he has a composite primary key, and some of the fields of this composite primary key constitute a foreign key to another entity. @PrimaryKeyJoinColumn is used when a primary key is also a foreign key. – JB Nizet Aug 22 '11 at 11:51
0
public class User implements Serializable {
    /**
     * 
     */
    private static final long serialVersionUID = 5478661842746845130L;
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private int id;
}
@Entity
public class Author {

    @Id
    @Column(name = "AUTHOR_ID", nullable = false)
    private int authorId;
    @Column(name = "ENABLED", nullable = false, length = 1)
    private boolean enabled;

    @OneToOne
    @MapsId
    @JoinColumn(name = "AUTHOR_ID", referencedColumnName = "ID", nullable = false, insertable = false, updatable = false)
    User user;

    public boolean isEnabled() {
        return enabled;
    }

    public void setEnabled(boolean enabled) {
        this.enabled = enabled;
    }

    public User getUser() {
        return user;
    }

    public void setUser(User user) {
        this.user = user;
    }

}
Sandy
  • 11
  • 2
  • My problem was little bit different, in my case the `User` entity has `username` and `email` as PK (so I can have the same username associated to different email) and `Author` having the same PK as `User` (`username`, `email`) and also `vatCode`, not just an `id` as in your example ;) – rascio May 18 '17 at 14:17
0

For Table A you can make you of embeddedId

@Emebddable
class PrimaryKeyIdTableA{
 private Integer firstId,

 private Integer secondId
}


class A {
 @EmebddedId
 private PrimaryKeyIdTableA id
}

For Table B you can use Idclass also as shown below

Class PrimaryKeyIdTableB {

private PrimaryKeyIdTableA id,

private Integer thirdId

 }

 @Idclass(PrimaryKeyIdTableB.class)
 Class TableB{
 @Id
 private Integer thirdId,
 
  @Id
  @onetoone
  @Joincolumns({
  @Joincolumn(name=firstid),
  @Joincolumn(name=secondId)})
 private PrimaryKeyIdTableA id
    }
unknown
  • 412
  • 7
  • 20