Hibernate 复合键和重叠字段 - 如何避免列重复
Hibernate composite key and overlapping field - how to avoid column duplication
我遇到了如何管理特定模型映射的问题。
这是一个多租户应用程序,我们选择在每个实体中包含 "tenant_id",因此我们不必每次需要获取实体时都进行联合(实际上,这是我问题的根源...)。
型号如下:
+--------------------+ +---------------+
| Book | | Author |
+--------------------+ +---------------+
| id (pk) | | id (pk) |
| tenant_id (pk)(fk) | | tenant_id (pk |
| author_id (fk) | | name |
| title | +---------------+
+--------------------+
如您所见,tenant-id 在每个实体中,并且是主键的一部分。我们使用@IdClass 来管理组合键。这是代码:
@Data
public class TenantAwareKey implements Serializable {
private UUID id;
private Integer tenantId;
}
@IdClass(TenantAwareKey.class)
@Entity
@Table(name = "BOOK")
@Data
public class Book {
@Id
@GeneratedValue
@Column(name = "ID")
private UUID id;
@Id
@Column(name = "TENANT_ID")
private Integer tenantId;
private String title;
@ManyToOne
@JoinColumns(
value = {
@JoinColumn(referencedColumnName = "id", name = "author_id"),
@JoinColumn(referencedColumnName = "tenant_id", name = "tenant_id", insertable = false, updatable = false)
})
private Author author;
}
@IdClass(TenantAwareKey.class)
@Entity
@Data
public class Author {
@Id
@GeneratedValue
@Column(name = TenantAwareConstant.ENTITY_ID_COLUMN_NAME)
private UUID id;
@Id
@Column(name = TenantAwareConstant.TENANT_ID_COLUMN_NAME)
private Integer tenantId;
private String name;
}
然后,当 运行 我的申请结束时:
Caused by: org.hibernate.AnnotationException: Mixing insertable and non insertable columns in a property is not allowed:
com.pharmagest.durnal.tenant.entity.BookNoDuplicateColumn.author
at org.hibernate.cfg.Ejb3Column.checkPropertyConsistency(Ejb3Column.java:725)
at org.hibernate.cfg.AnnotationBinder.bindManyToOne(AnnotationBinder.java:3084)
(...)
如果我不尝试 "mutualize" tenant_id 列,我设法让它工作,当我只有一个外键与此 tenant_id 时,它是可以接受的,但随着外键数量的增加越来越少,导致每次添加一个 tenant_id 列,重复信息和破坏内存...
深入挖掘后,我在 Hibernate 中发现了一个未解决的问题:https://hibernate.atlassian.net/browse/HHH-6221
多年来一直没有修复...所以,我的问题是:您是否遇到过这样的映射,当我有一个共享字段的外键时,是否有避免重复列的解决方案主键?
如 here 所述,您可以通过对列 id_tenant.
使用 @JoinColumnOrFormula 来绕过验证
你应该这样映射作者的协会:
@JoinColumnsOrFormulas(
value = {
@JoinColumnOrFormula(column = @JoinColumn(referencedColumnName = "id", name = "author_id")),
@JoinColumnOrFormula(formula = @JoinFormula(referencedColumnName = "tenant_id", value = "tenant_id"))
})
我遇到了如何管理特定模型映射的问题。
这是一个多租户应用程序,我们选择在每个实体中包含 "tenant_id",因此我们不必每次需要获取实体时都进行联合(实际上,这是我问题的根源...)。
型号如下:
+--------------------+ +---------------+
| Book | | Author |
+--------------------+ +---------------+
| id (pk) | | id (pk) |
| tenant_id (pk)(fk) | | tenant_id (pk |
| author_id (fk) | | name |
| title | +---------------+
+--------------------+
如您所见,tenant-id 在每个实体中,并且是主键的一部分。我们使用@IdClass 来管理组合键。这是代码:
@Data
public class TenantAwareKey implements Serializable {
private UUID id;
private Integer tenantId;
}
@IdClass(TenantAwareKey.class)
@Entity
@Table(name = "BOOK")
@Data
public class Book {
@Id
@GeneratedValue
@Column(name = "ID")
private UUID id;
@Id
@Column(name = "TENANT_ID")
private Integer tenantId;
private String title;
@ManyToOne
@JoinColumns(
value = {
@JoinColumn(referencedColumnName = "id", name = "author_id"),
@JoinColumn(referencedColumnName = "tenant_id", name = "tenant_id", insertable = false, updatable = false)
})
private Author author;
}
@IdClass(TenantAwareKey.class)
@Entity
@Data
public class Author {
@Id
@GeneratedValue
@Column(name = TenantAwareConstant.ENTITY_ID_COLUMN_NAME)
private UUID id;
@Id
@Column(name = TenantAwareConstant.TENANT_ID_COLUMN_NAME)
private Integer tenantId;
private String name;
}
然后,当 运行 我的申请结束时:
Caused by: org.hibernate.AnnotationException: Mixing insertable and non insertable columns in a property is not allowed:
com.pharmagest.durnal.tenant.entity.BookNoDuplicateColumn.author
at org.hibernate.cfg.Ejb3Column.checkPropertyConsistency(Ejb3Column.java:725)
at org.hibernate.cfg.AnnotationBinder.bindManyToOne(AnnotationBinder.java:3084)
(...)
如果我不尝试 "mutualize" tenant_id 列,我设法让它工作,当我只有一个外键与此 tenant_id 时,它是可以接受的,但随着外键数量的增加越来越少,导致每次添加一个 tenant_id 列,重复信息和破坏内存...
深入挖掘后,我在 Hibernate 中发现了一个未解决的问题:https://hibernate.atlassian.net/browse/HHH-6221
多年来一直没有修复...所以,我的问题是:您是否遇到过这样的映射,当我有一个共享字段的外键时,是否有避免重复列的解决方案主键?
如 here 所述,您可以通过对列 id_tenant.
使用 @JoinColumnOrFormula 来绕过验证你应该这样映射作者的协会:
@JoinColumnsOrFormulas(
value = {
@JoinColumnOrFormula(column = @JoinColumn(referencedColumnName = "id", name = "author_id")),
@JoinColumnOrFormula(formula = @JoinFormula(referencedColumnName = "tenant_id", value = "tenant_id"))
})