Yes, it is but you need to make it elegant. The following super-class can be used to define arbitrary many-to-many relationship as an entity:
@MappedSuperclass
public abstract class ModelBaseRelationship {
@Embeddable
public static class Id implements Serializable {
public Long entityId1;
public Long entityId2;
@Column(name = "ENTITY1_ID")
public Long getEntityId1() {
return entityId1;
}
@Column(name = "ENTITY2_ID")
public Long getEntityId2() {
return entityId2;
}
public Id() {
}
public Id(Long entityId1, Long entityId2) {
this.entityId1 = entityId1;
this.entityId2 = entityId2;
}
@Override
public boolean equals(Object other) {
if (other == null)
return false;
if (this == other)
return true;
if (!(other instanceof Id))
return false;
final Id that = (Id) other;
return new EqualsBuilder().append(this.entityId1, that.getEntityId1()).append(this.entityId1, that.getEntityId2()).isEquals();
}
@Override
public int hashCode() {
return new HashCodeBuilder(11, 111).append(this.entityId1).append(this.entityId2).toHashCode();
}
protected void setEntityId1(Long theEntityId1) {
entityId1 = theEntityId1;
}
protected void setEntityId2(Long theEntityId2) {
entityId2 = theEntityId2;
}
}
protected Id id = new Id();
public ModelBaseRelationship() {
super();
}
public ModelBaseRelationship(ModelBaseEntity entity1, ModelBaseEntity entity2) {
this();
this.id.entityId1 = entity1.getId();
this.id.entityId2 = entity2.getId();
setVersion(0);
}
@EmbeddedId
public Id getId() {
return id;
}
protected void setId(Id theId) {
id = theId;
}
}
The example of entity based on this super class (fragment):
@Entity(name = "myRealEntity")
@Table(name = "REAL_TABLE_NAME", uniqueConstraints = { @UniqueConstraint(columnNames = {
"FIRST_FK_ID", "SECOND_FK_ID" }) })
@AttributeOverrides( {
@AttributeOverride(name = "entityId1", column = @Column(name = "FIRST_FK_ID")),
@AttributeOverride(name = "entityId2", column = @Column(name = "SECOND_FK_ID"))
})
public class ModelBaseRelationshipReferenceImpl extends ModelBaseRelationship {
private Entity1OfManyToManyRelationship entity1;
private Entity2OfManyToManyRelationship entity2;
...
@ManyToOne
@JoinColumn(name = "FIRST_FK_ID", insertable = false, updatable = false)
public Entity1OfManyToManyRelationship getEntity1OfManyToManyRelationship() {
return entity1;
}
@ManyToOne
@JoinColumn(name = "SECOND_FK_ID", insertable = false, updatable = false)
public Entity2OfManyToManyRelationship getEntity2OfManyToManyRelationship () {
return entity2;
}
...
}