JPA How to Make Composite Foreign Key Part of Composite Primary Key

JPA how to make composite Foreign Key part of composite Primary Key

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

JPA make a part of the composite foreign key part of primary key

I'm not entirely sure I understand your question; but I would map your classes like this (the primary difference being CompositeJoinId):

public class CompositeId implements Serializable {
private Long id;

private Long version;

// Other stuff...
}

@Entity
@IdClass(CompositeId.class)
public class A {
@Id
private Long id;

@Id
private Long version;

private String name;

private String creatorName;

// Other stuff...
}

@Entity
public class B {
@Id
private Long id;

private String name;

// Othet stuff...
}

public class CompositeJoinId implements Serializable {
private Long aId;

private Long bReference; // matches name of @Id attribute and type of B PK

// Other stuff...
}

@IdClass(CompositeJoinId.class)
@Entity
public class C {
@Id
@Column(name = "a_id", insertable = false, updatable = false)
Long aId;

@Id
@ManyToOne
@JoinColumn(name = "b_id")
private B bReference;

@ManyToOne
@JoinColumns({
@JoinColumn(name="a_id", referencedColumnName="id"),
@JoinColumn(name="a_version", referencedColumnName="version")
})
private A aReference;

private Long day;

// Other stuff...
}

These are examples of derived identities; and derived identities are discussed (with examples) in the JPA 2.2 spec in section 2.4.1.

How to make composite Foreign Key part of composite Primary Key with Spring Boot - JPA

When you use the save() method, entityManager checks if the entity is new or not. If yes, the entity will be saved, if not, it'll be merged

If you implement your Entity Class with the inteface Persistable, you can override the method isNew() and make it returns True. In that case the save() method will persist, and not merge, your entity.

Mapping a composite foreign key to a composite primary key

You should restore the mappedBy="leg" to the PriceRequestLegModel @OneToMany annotation:

@Entity(name = "PriceRequestLeg")
public class PriceRequestLegModel {

@EmbeddedId
private PriceRequestLegKey legKey;
@OneToMany(mappedBy="leg", cascade = CascadeType.ALL)
private List<AllocationModel> allocations;
...
}

Then you should change AllocationKey to reference PriceRequestLegKey:

@Embeddable
public class AllocationKey implements Serializable {

PriceRequestLegKey legKey; // corresponds to PK type of PriceRequestLegModel
@Column(name = "allocation_index")
private int allocationIndex;
...
}

And then set the value of the Allocation.leg @MapsId annotation appropriately:

@Entity(name = "Allocation")
public class AllocationModel {

@EmbeddedId
private AllocationKey allocationKey;
@ManyToOne
@MapsId("legKey")
@JoinColumns({
@JoinColumn(name = "leg_request_id", referencedColumnName = "leg_request_id"),
@JoinColumn(name = "display_index", referencedColumnName = "display_index")
})
private PriceRequestLegModel leg;
...
}

Some examples like this are in the JPA 2.2 spec section 2.4.1.

Composite primary key, foreign key. Reference to object or key?

Referring to the JPA 2: composite primary key classes discussion, make the following changes to the Foo and FooPK classes:

@Entity
public class Foo {

@EmbeddedId
private FooPK key;

@MapsId("barId") //references EmbeddedId's property
@JoinColumn(name = "bar_id", referencedColumnName = "id")
@ManyToOne
private Bar bar;
}

@Embeddable
public class FooPK {

@Column(name = "id")
private int id;
@Column(name = "bar_id")
private int barId;
}

I suggest first making it work with FIELD access and then apply PROPERTY access.

So what to do? Go with the first solution and keep the ids in sync
manually or is there another (best) practice?

Save yourself from pain - generate ids automatically.

JPA & Hibernate - Composite primary key with foreign key

You have multiple things wrong. If you are using @EmbeddedId then the you ID class needs to be an embeddable.

@Embeddable
public class InteractionId {
@Column(name="name")
String name;
Long drugId; //type should be same as for ID field on Medicine

//equals and hashcode etc.
}

You also need a relationship from DrugInteraction to Medicine annotated with MapsId:

@Entity
@Table(name = "drugInteractions")
public class DrugInteraction {

@EmbeddedId
private InteractionId interactionId;

@MapsId("drugId")//value corresponds to property in the ID class
@ManyToOne
@JoinColumn(name = "drug_id")
private Medicine medicine;
}

To save a new instance:

DrugInteraction di = new DrugInteraction();
Medicine medicine = //an existing medicine
di.setName("Some Name");
di.setMedicine(medicine);
//save

As an alternative, can also do this using an IDClass rather than EmbeddedId:

//not an embeddable
public class InteractionId {
String name;
Long drugId; //type should be same as for ID field on Medicine

//equals and hashcode etc.
}

and change the mappings:

@Entity
@Table(name = "drugInteractions")
@IdClass(InteractionId.class) //specify the ID class
public class DrugInteraction {

@Id
private String name;

@Id
@ManyToOne
@JoinColumn(name = "drug_id")
private Medicine medicine;
}


Related Topics



Leave a reply



Submit