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
How to Use a Java8 Lambda to Sort a Stream in Reverse Order
"Not Allowed to Load Local Resource: File:///C:....Jpg" Java Ee Tomcat
How to Deserialize a List Using Gson or Another JSON Library in Java
Converting a Date Object to a Calendar Object
In Which Language Are the Java Compiler and Jvm Written
Do/Can Abstract Classes Replace Interfaces
Environment Variable with Maven
How to "Add" to Classpath Dynamically in Java
Things Possible in Intellij That Aren't Possible in Eclipse
Java Creating a New Objectinputstream Blocks
Difference Between Openjdk and Adoptium/Adoptopenjdk
Differencebetween Putting a Property on Application.Yml or Bootstrap.Yml in Spring Boot
How to Do Query Auto-Completion/Suggestions in Lucene
Parsing a Fixed-Width Formatted File in Java
How to Determine If a Point Is Inside a 2D Convex Polygon