NickJ
NickJ

Reputation: 9559

JPA entity with composite primary and foreign keys

I have an entity with a composite primary key consisting of two fields, one of which is also part of a composite foreign key.

Background: I have entities Person,Area, and Session.

Person has many-to-many relationships with Area and Session, using join entities called PersonArea and PersonSession.

So, I have PersonSession, with primary key of (personId, sessionId). PersonId and SessionId are themselves foreign keys to Person and Session.

PersonSession also has a field areaId. I want (personId, areaId) to be a composite foreign key to PersonArea.

My code for PersonSession:

@Entity
@Table(name="person_session")
@IdClass(PersonSession.ID.class)
public class PersonSession {

  @Id
  private int personId ;

  @Id
  private int sessionId;

  @ManyToOne
  @JoinColumn(name = "personId", updatable = false, insertable = false, referencedColumnName = "id")
  private Person person;

  @ManyToOne
  @JoinColumn(name = "sessionId", updatable = false, insertable = false, referencedColumnName = "id")
  private Session session;

  @ManyToOne//(cascade = CascadeType.ALL)
  @JoinColumns({
    @JoinColumn(name = "personId", updatable = false, insertable = false),
    @JoinColumn(name = "areaId", updatable = false, insertable = false),
  })
  private PersonArea personArea;

}

Code for PersonSession.Id

public static class ID implements Serializable {
    private int personId;
    private int sessionId;
}

This seems OK, it creates all the correct relationships in the database. The problem comes when I try to insert PersonSession objects - the areaId column is always null, I think that is because it's defined a updatable=false, insertable=false.

However, if I try and make it updatable and insertable, I get an exception complaining the personId is a repeated column:

Caused by: org.hibernate.MappingException: Repeated column in mapping for entity: foo.bar.PersonSession column: personId (should be mapped with insert="false" update="false")

How can I have the required relationships AND have areaId updatable and insertable?

Upvotes: 2

Views: 3200

Answers (2)

Spyros El.
Spyros El.

Reputation: 423

I know I am late but I faced the same problem and I used @JoinColumnsOrFormulas to resolve it. Here is what you could do:

@JoinColumnsOrFormulas(value = {
        @JoinColumnOrFormula(column = @JoinColumn(name="personId", referencedColumnName = "personId")),
        @JoinColumnOrFormula(formula = @JoinFormula(value="areaId", referencedColumnName = "areaId"))}) 
private PersonArea personArea;

Upvotes: 0

NickJ
NickJ

Reputation: 9559

I should be able to do what I want with this:

@ManyToOne//(cascade = CascadeType.ALL)
@JoinColumns({
  @JoinColumn(name = "personId"),
  @JoinColumn(name = "areaId", updatable = false, insertable = false),
})
private PersonArea personArea;

But Hibernate does not support mixing updatable and non updatable Join Columns. The accepted answer to this question indicates that it might be supported at some time, but it seems the developers aren't very worried about that shortcoming.

I have how ditched Hibernate in favour of Eclipselink and it works!

Upvotes: 1

Related Questions