Hibernate复合键和重叠字段-如何避免列重复 [英] Hibernate composite key and overlapping field - how to avoid column duplication

查看:68
本文介绍了Hibernate复合键和重叠字段-如何避免列重复的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正面临有关如何管理特定模型的映射的问题.

I am facing a problem about how to manage mapping for a specific model.

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

This is a multitenant application, and we have made the choice of including the "tenant_id" in every entity, so we don't have to make a joint everytime we need to get an entity (in fact, this is the root of my problem...).

模型如下:

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

如您所见,tenant-id在每个实体中,并且是主键的一部分.我们使用@IdClass来管理组合键.这是代码:

As you can see, the tenant-id is in each entity, and part of the primary key. We use @IdClass to manage the composite key. Here is the code :


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

然后,在运行我的应用程序时,我最终得到了:

And then, when running my application I ended up with :


    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列,从而导致信息重复并破坏内存...

I manage to make it work if I don't try to "mutualize" the tenant_id column, it can be acceptable when I have only one foreign key with this tenant_id, but less and less as the number of foreign key increase, resulting in adding a tenant_id column each time, duplicating information et spoiling memory...

深入研究之后,我在Hibernate中发现了一个未解决的问题: https://hibernate.atlassian.net/browse/HHH-6221

After digging a bit, I found an open issue in Hibernate : https://hibernate.atlassian.net/browse/HHH-6221

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

It has not been fixed for years... So, my question is : Have you faced a mapping like this, and is there a solution to avoid duplicated columen when I have a foreign-key that share a field with the primary key?

推荐答案

此处所述,您可以绕过验证通过对列id_tenant使用@JoinColumnOrFormula.

As described here, you can bypass the validation by using @JoinColumnOrFormula for the column id_tenant.

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

You should map the author's association like this:

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

这篇关于Hibernate复合键和重叠字段-如何避免列重复的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆