40

I have following tables how can i map them to JPA entities:

TABLE Event {
    EventID
    SourceID
    ....Other event fields
    PK (EventID, SourceID)
}

TABLE MEETING {
    MeetingID
    EventID
    SourceID
    ...Other meeting fields
    PK(MeetingID,EventID, SourceID)
    FK(EventID, SourceID) //FK with Event table
}

The Event table has one-to-many relationship with Meeting table. How can i map this bi-directional relationship in JPA?

Jin Kwon
  • 18,308
  • 12
  • 99
  • 160
suraj bahl
  • 2,585
  • 5
  • 26
  • 40
  • We got what you want to say but you may wanna edit your question. A table cannot have multiple Primary Keys. http://stackoverflow.com/questions/20742922/can-a-table-have-multiple-primary-keys – Raman Sahasi Jul 13 '15 at 17:28

2 Answers2

44
@Embeddable
public class EventID {
    public int eventID;
    public int sourceID;
}

@Entity
public class Event {
    @EmbeddedId
    public EventID id;

    @OneToMany(mappedBy="event")
    public Collection<Meeting> meetings;
}

@Embeddable
public class MeetingID {
    public EventID eventID; // corresponds to ID type of Event
    public int meetingID;
}

@Entity
public class Meeting {
    @EmbeddedId
    public MeetingID id;

    @MapsId("eventID")
    @JoinColumns({
        @JoinColumn(name="EventID", referencedColumnName="EventID"),
        @JoinColumn(name="SourceID", referencedColumnName="SourceID")
    })
    @ManyToOne
    public Event event;
}

Discussed in JPA 2.1 spec, section 2.4.1.

Brian Vosburgh
  • 2,981
  • 1
  • 16
  • 18
  • In this case, do I need to set meetingID manually? Or Can i generate randomically? – Cristiano Bombazar Sep 20 '19 at 01:14
  • 1
    @CristianoBombazar - you can set meetingID either way; but it is probably more common to set the value manually, as it typically has some semantic meaning and/or is scoped by the associated Event. Thus the composite primary key. – Brian Vosburgh Sep 20 '19 at 13:16
  • I have a similar situation where my pk and FK share a field, but not all FK fields are in pk. I managed to make it work with your example, however, I always had to set meetingID manually. Is this behavior correct? – Cristiano Bombazar Sep 20 '19 at 14:27
  • 1
    @CristianoBombazar - yes, you will need to set meetingID manually. – Brian Vosburgh Sep 21 '19 at 23:35
  • 2
    Do I have set both meeting Id and event? Since event is mapped by eventId in meetingId would it not be enough to set meetingId? – Andrews Dec 25 '20 at 12:55
10
@Entity
public class Event {

    @EmbeddedId
    private EventId id;

    @OneToMany(mappedBy = "event")
    private List<Meeting> meetings = new ArrayList<>();
}

@Embeddable
public class EventId implements Serializable {

    @Column(name = "EventID")
    private Long eventId;

    @Column(name = "SourceID")
    private Long sourceId;

    //implements equals and hashCode
}

@Entity
public class Meeting {

    @EmbeddedId
    private MeetingId id; 

    @MapsId("eventId")
    @JoinColumns({
        @JoinColumn(name="EventID", referencedColumnName="EventID"),
        @JoinColumn(name="SourceID", referencedColumnName="SourceID")
    })
    @ManyToOne
    private Event event;
}

@Embeddable
public class MeetingId implements Serializable {

    @Column(name = "MeetingID")
    private Long meetingId;

    private EventId eventId;

    //implements equals and hashCode
}

You may want to take a look at a similar question for more details.

Community
  • 1
  • 1
Dragan Bozanovic
  • 22,362
  • 4
  • 40
  • 106