Reputation: 263
I am new in eclipselink and trying to add extra columns in manyTomany association table.
so i decide to use two @OneToMany and @ManyToOne to replace @ManyToMany relationship.
i have tried the hibernate way in the following link, but it does't work. http://www.mkyong.com/hibernate/hibernate-many-to-many-example-join-table-extra-column-annotation/
Is there anyone know how to build this in eclispelink?
Thanks
-------------------------just follow the link above and paste test code --------------
SideA:
@Entity
@Table(name = "SideA")
public class SideA {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private long id;
private List<ABAssociation> association = new ArrayList<ABAssociation>();
@OneToMany(fetch = FetchType.LAZY, mappedBy = "pk.sideA", cascade=CascadeType.ALL)
public List<ABAssociation> getAssociation() {
return this.association;
}
public void setAssociation(List<ABAssociation> association) {
this.association = association;
}
}
SideB:
@Entity
@Table(name = "SideB")
public class SideB {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private long id;
private List<ABAssociation> association = new ArrayList<ABAssociation>();
@OneToMany(fetch = FetchType.LAZY, mappedBy = "pk.sideB", cascade=CascadeType.ALL)
public List<ABAssociation> getAssociation() {
return this.association;
}
public void setAssociation(List<ABAssociation> association) {
this.association = association;
}
}
Associtation:
@Entity
@Table(name = "ABAssociation")
@AssociationOverrides({
@AssociationOverride(name = "pk.sideA",
joinColumns = @JoinColumn(name = "SIDEA_ID")),
@AssociationOverride(name = "pk.sideB",
joinColumns = @JoinColumn(name = "SIDEB_ID")) })
public class ABAssociation {
private ABAssociationPK pk = new ABAssociationPK();
@EmbeddedId
public ABAssociationPK getPk() {
return pk;
}
public void setPk(ABAssociationPK pk) {
this.pk = pk;
}
@Transient
public SideA getSideA() {
return getPk().getSideA();
}
public void setSideA(SideA sideA) {
getPk().setSideA(sideA);
}
@Transient
public SideB getSideB() {
return getPk().getSideB();
}
public void setSideB(SideB sideB) {
getPk().setSideB(sideB);
}
private String extracolumn;
}
ABAssociationPK:
@Embeddable
public class ABAssociationPK implements java.io.Serializable{
private static final long serialVersionUID = -3797694126054440157L;
private SideA sideA;
private SideB sideB;
public ABAssociationPK(){}
@ManyToOne
public SideA getSideA() {
return sideA;
}
public void setSideA(SideA sideA) {
this.sideA = sideA;
}
@ManyToOne
public SideB getSideB() {
return sideB;
}
public void setSideB(SideB sideB) {
this.sideB = sideB;
}
}
the exception is :Exception Description: Predeployment of PersistenceUnit [testPU] failed.
Internal Exception: Exception [EclipseLink-7298] (Eclipse Persistence Services - 2.3.2.v20111125-r10461): org.eclipse.persistence.exceptions.ValidationException
Exception Description: The mapping [sideA] from the embedded ID class [class com.fuhu.nabisync.resource.model.entity.ABAssociationPK] is an invalid mapping for this class. An embeddable class that is used with an embedded ID specification (attribute [pk] from the source [class com.fuhu.nabisync.resource.model.entity.ABAssociation]) can only contain basic mappings. Either remove the non basic mapping or change the embedded ID specification on the source to be embedded.
Upvotes: 0
Views: 4212
Reputation: 691635
The message is pretty clear:
An embeddable class that is used with an embedded ID specification can only contain basic mappings.
So, you can't have a ManyToOne association inside the ABAssociationPK class.
The standard JPA way of doing this is to use the @MapsId
annotation. The javadoc provides a helpful example. In your particular situation, the ABAssociationPK
class should contain two fields of type long
: aId
and bId
, mapped as basic columns.
The Association
entity should contain the associations, and use the @MapsId
annotation:
@ManyToOne
@MapsId("aId")
public SideA getSideA() {
return sideA;
}
@ManyToOne
@MapsId("bId")
public SideB getSideB() {
return sideB;
}
Upvotes: 3