Jadiel de Armas
Jadiel de Armas

Reputation: 8802

JPA Mapping of Association table where one of the entities has composite key

I have the following model that I need to annotate using JPA:

I cannot figure out how to map the association table. Mapping Merchant is straitghtforward, so I will leave it outside of the mappings. The other mappings are as follows:

MerchantType:

@Entity
class MerchantType {

    @EmbeddedId
    @AttributeOverrides({
         @AttributeOverride(name = "e1_id", column=@Column(name="e1_id")),
         @AttributeOverride(name = "another_id", column=@Column(name="another_id"))
    })        
    MerchantTypePk id;

    @ManyToOne
    @JoinColumn(name = "e1_id", referencedColumnName = "e1_id", insertable = false, nullable = false)
    @MapsId("e1_id")
    AnotherEntity1 e1;


    @Column(name = "another_id", referencedColumnName = "another_id", insertable = false, nullable = false)
    Long anotherId;

    //Two other local fields irrelevant to the discussion here

    public MerchantType(){
        this.id = new MerchantTypePk();
    }

    //Getters and setters here.
}

//MerchantTypePk is a simple Embeddable class here below with two Long fields:
//e1_id and another_id

MerchantMerchantTypeAssociation:

@Entity
class MerchantMerchantTypeAssociation {

     @EmbeddedId
     @AttributeOverrides({
           @AttributeOverride(name = "e1_id", column = @Column(name = "e1_id")),
           @AttributeOverride(name = "another_id", column = @Column(name = "another_id"))
           @AttributeOverride(name = "offer_id", column = @Column(name = "merchant_id"))
     })
     private MerchantMerchantTypeAssociationPk id;
     //******** HERE IS THE QUESTION
     //******** HERE IS THE QUESTION
     //******** HERE IS THE QUESTION
     @ManyToOne
     @JoinColumns({
          @JoinColumn(name = "e1_id", referencedColumnName = "e1_id", insertable = false, updatable = false),
          @JoinColumn(name = "another_id", referencedColumnName = "another_id", insertable = false, updatable = false)
     })
     @MapsId("e1_id")
     @MapsId("another_id")
     private MerchantType merchantType;

     //Similar mapping to the one above, but with only one Join Column  
     private Merchant merchant;

     //One more local field that is irrelevant to the mapping
     //but is the one that is forcing me to map a many - to - many relationship
     //in this way.

}

//MerchantMerchantTypeAssociationPk as a simple embeddable

Question: How can I make a mapping for this kind of entities when the annotation '@MapsId' cannot be repeated and it does not accept more than one value?

Upvotes: 0

Views: 163

Answers (1)

Brian Vosburgh
Brian Vosburgh

Reputation: 3276

You did not include the code for MerchantMerchantTypeAssociationPk, but I'm guessing it looks like this:

@Embeddable
public class MerchantMerchantTypeAssociationPk {
    public MerchantPk merchantPK;
    public MerchantTypePk merchantTypePK;
}

@MapsId is used to specify the attribute within the composite key to which the relationship attribute corresponds, not the columns. So MerchantMerchantTypeAssociation should look like this:

@Entity class MerchantMerchantTypeAssociation {

    @EmbeddedId
    private MerchantMerchantTypeAssociationPk id;

    @ManyToOne
    @JoinColumns({
         @JoinColumn(name = "e1_id", referencedColumnName = "e1_id",...),
         @JoinColumn(name = "e2_id", referencedColumnName = "e2_id",...)
    })
    @MapsId("merchantTypePK") // <<< *attribute* in Embeddable
    private MerchantType merchantType;

    @ManyToOne
    @JoinColumn(name = "m_id", referencedColumnName = "merchant_id",...)
    @MapsId("merchantPK") // <<< *attribute* in Embeddable
    private Merchant merchant;
}

Derived identities are discussed in the JPA 2.1 spec, section 2.4.1.

Upvotes: 1

Related Questions