I have master record named Offer with an ID. I have a detail record named Offer_Cost with a composite key consisting of the Offer ID and a date. I would like to create the association between Offer and Offer_Cost (ONE_TO_MANY).
I can’t figure out how to enter the Association into Studio, since the Offer ID is already part of the Embedded key. When I create a separate field for the Association, I end up with the error “Multiple writable mappings exist for the field [OFFER_COST.OFFER_ID]. Only one may be defined as writable, all others must be read-only”. I guess I could go into the Java and add “updatable=false, insertable=false” to get a read-only field, but is this the best way to handle the problem?
Is there a best practice for specifying an association that is part of a composite(embedded) key?
And, here again, I get to answer my own question after a lot of research. Hopefully other people will find this useful. And, as always, I am open to better suggestions. The reference for this is MapsId (EclipseLink 2.0.2, build 'v20100323-r6872' API Reference)
In my Composite Key, I have this:
public class OfferCostCompKey extends EmbeddableEntity {
@Column(name = "OFFER_ID", nullable = false)
protected Long offer_id;
@Temporal(TemporalType.DATE)
@Column(name = "START_DATE", nullable = false)
protected Date startDate;
.
.
.
}
The trick is the @MapsId and the @JoinColumn setting. The @MapsId tells Eclipselink the name of the field inside my composite key (offer_id). The @JoinColumn tells Eclipselink the name of the field in OfferCost that should be used to join with Offers.
This appears to work. Please comment if I am misunderstanding something or if there is a more “cuba-ish” way.
I came to the same your solution with @MapsId for a single key. I have also solved the problem of a composite key inside another composite key in OneToMany relationship, but without MapsId, I used the @JoinColumns annotation with the list of referenceColumnName and nullable = false, insertable = false, updatable = false.