EJB3 - 处理非标准链接表

时间:2022-09-06 20:10:31

I have a situation where I am working with EJB3 and a legacy database. I have a situation where there is a many-to-many relationship between two tables A and B, defined through a third (link) table L.

我有一种情况,我正在使用EJB3和遗留数据库。我有一种情况,即两个表A和B之间存在多对多关系,通过第三个(链接)表L定义。

The complication is that the link table has other fields in it other than the PK's of tables A and B. The columns are standard timestamp and user columns to record who generated the link. These two additional columns are preventing me from defining the many-many relationship using a join table annotation, as they are not nillable and so must be populated.

复杂的是链接表除了表A和B的PK之外还有其他字段。列是标准时间戳和用户列,用于记录生成链接的人员。这两个额外的列阻止我使用连接表注释定义多对多关系,因为它们不是可填充的,因此必须填充。

Does anyone know of a way around this limitation? I could define One-to-many relationships from the link table to each of the other tables in the relationship, but this is not very elegant.

有没有人知道解决这个限制的方法?我可以定义从链接表到关系中每个其他表的一对多关系,但这不是很优雅。

Thanks,

1 个解决方案

#1


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

#1


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