【问题标题】:Hibernate composite key and overlapping field - how to avoid column duplicationHibernate复合键和重叠字段 - 如何避免列重复
【发布时间】:2019-02-21 16:54:54
【问题描述】:

我面临如何管理特定模型的映射的问题。

这是一个多租户应用程序,我们已经选择在每个实体中包含“tenant_id”,因此我们不必每次需要获取实体时都进行联合(实际上,这是根我的问题...)。

型号如下:

+--------------------+   +---------------+
|        Book        |   |    Author     |
+--------------------+   +---------------+
| id (pk)            |   | id (pk)       |
| tenant_id (pk)(fk) |   | tenant_id (pk |
| author_id (fk)     |   | name          |
| title              |   +---------------+
+--------------------+

如您所见,租户 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)
    (...)

如果我不尝试“共同化”tenant_id 列,我设法让它工作,当我只有一个外键和这个tenant_id 时它是可以接受的,但随着外键数量的增加越来越少,导致每次都添加一个tenant_id列,重复信息和破坏内存......

经过一番挖掘,我在 Hibernate 中发现了一个未解决的问题:https://hibernate.atlassian.net/browse/HHH-6221

多年来一直没有修复...所以,我的问题是:您是否遇到过这样的映射,当我有一个与主共享字段的外键时,是否有避免重复列的解决方案钥匙?

【问题讨论】:

  • 搜索@EmbeddedId注解的使用方法,需要为Id创建单独的Entity类
  • 起初我在考虑使用@EmbeddedId,但它有一个限制,因为我的主键的一部分是@GeneratedValue,而且你可以在这个问题中看到它是不可能的: hibernate.atlassian.net/browse/HHH-6044

标签: java hibernate multi-tenant composite-key


【解决方案1】:

here 所述,您可以通过对列 id_tenant 使用 @JoinColumnOrFormula 来绕过验证。

你应该像这样映射作者的关联:

    @JoinColumnsOrFormulas(
        value = {
                @JoinColumnOrFormula(column = @JoinColumn(referencedColumnName = "id", name = "author_id")),
                @JoinColumnOrFormula(formula = @JoinFormula(referencedColumnName = "tenant_id", value = "tenant_id"))
        })

【讨论】:

  • 谢谢,正是我需要的!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-10-06
  • 2015-01-28
  • 2017-08-23
  • 1970-01-01
  • 1970-01-01
  • 2023-01-13
  • 1970-01-01
相关资源
最近更新 更多