6

我有以下情况:

我正在尝试构建一个具有相同表的数据库中具有相同租户的多租户应用程序。正如我发现的那样,Hibernate 在 5.0 之前不支持此变体。

我试图通过向每个表添加一个brandId 字段来解决这个问题。

当我建立多对多关系时,我还将这个brandId添加到ManyToMany连接表,在这里(不知道我是否可以这样做,mysql没有抱怨)我为两个表创建了一个外键,同时都包含brandid

所以现在例如我有一个表 Text(ID,name,brandId) 和一个 Tag(ID,name,brandId) 和一个连接表 (text_id,tag_id,brand_id) ,其中外键是

CONSTRAINT FK_TAG_TEXTS_TAG FOREIGN KEY (TAG_ID,BRAND_ID) REFERENCES TAG (ID,brand),

CONSTRAINT FK_TAG_TEXTS_TEXT FOREIGN KEY (TEXT_ID,BRAND_ID) REFERENCES TEXT (ID,brand)

如您所见,品牌 ID 被使用了两次。

然后我使用 Hibernate Tools 生成了我的类,它创建了一个应有的复合主键类以及标记类中的关联。

  @ManyToMany(fetch = FetchType.EAGER,cascade = {CascadeType.PERSIST,CascadeType.MERGE })
  @JoinTable(name = "tag_texts", , joinColumns = {
    @JoinColumn(name = "TAG_ID", nullable = false, insertable = false, updatable = false),
    @JoinColumn(name = "BRAND_ID", nullable = false, insertable = false, updatable = false) }, inverseJoinColumns = { @JoinColumn(name = "TEXT_ID", insertable = false, nullable = false, updatable = false),@JoinColumn( name = "BRAND_ID",  insertable = false, nullable = false, updatable = false) })
public List<Text> getTexts() {
    return this.texts;
}

现在的问题是我得到以下异常:

org.hibernate.MappingException:集合映射中的重复列:de.company.domain.Tag.texts 列:brand_id

我查看了引发异常的 Collection 类中的 Hibernate 代码。这里调用了一个方法'checkColumnDupliation',它使用一个Set并插入名称,这意味着第二次插入“BRAND_ID”作为列会导致这种行为。

我发现重复列错误的最常见解决方案是在多个引用中使用同一列时插入“可插入 = 假和可更新 = 假”。此处对此进行了描述:
Hibernate: where do insertable = false, updatable = false 属于涉及外键的复合主键星座?

但这似乎与我的问题不同。

所以我的问题是:是否有可能使用 JPA 注释解决此问题并在 joinColumns 和 inverseJoinColumns 中使用品牌 ID?

4

1 回答 1

0

问题是您需要 3 个实体之间的 JoinTable TextTagBrand.

可能您将不得不使用IdClass,例如:

public class AssociationId implements Serializable {
  private long textId;
  private long tagId;
  private long brandId;

  hash and equals function
  ...
}

Id 类实体:

@Entity
@Table(name="tag_text_brand")
@IdClass(AssociationId.class)
public class TagTextBrandAssociation {
  @Id
  private long tagId;
  @Id
  private long textId;
  @Id
  private long textId;

  @ManyToOne
  @PrimaryKeyJoinColumn(name="TAG_ID", referencedColumnName="ID")
  private Tag tag;
  @ManyToOne
  @PrimaryKeyJoinColumn(name="TEXT_ID", referencedColumnName="ID")
  private Text text;
  @ManyToOne
  @PrimaryKeyJoinColumn(name="BRAND_ID", referencedColumnName="ID")
  private Brand brand;
  ...
}

您可以在您的 3 个实体中使用它,如下所示:

@Entity
public class Text {
  @Id
  private long id;
  ...
  @OneToMany(mappedBy="text")
  private List<TagTextBrandAssociation> tagsAndBrands;
  ...
}

请参阅此处了解更多信息。

于 2013-11-19T12:25:17.503 回答