Association with portion of an Embedded key

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 http://www.eclipse.org/eclipselink/api/2.0.2/javax/persistence/MapsId.html

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;
     .
     .
     .
}

In my master entity (Offer), I have this:


@OneToMany(mappedBy = "offer")
protected List<OfferCost> offerCost;

In my detail entity (OfferCost), I have this:


@EmbeddedId
protected OfferCostCompKey id;

@JoinColumn(name = "OFFER_ID")
@MapsId("offer_id")
@ManyToOne(fetch = FetchType.LAZY)
Offer offer;

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.

Hi Eric,

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.

I hope can be useful.