Hibernate 复合键和重叠字段 - 如何避免列重复

2024-01-03

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

这是一个多租户应用程序,我们选择在每个实体中包含“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 https://hibernate.atlassian.net/browse/HHH-6221

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


如上所述here https://stackoverflow.com/a/13147366/3869137,您可以通过对 id_tenant 列使用 @JoinColumnOrFormula 来绕过验证。

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

    @JoinColumnsOrFormulas(
        value = {
                @JoinColumnOrFormula(column = @JoinColumn(referencedColumnName = "id", name = "author_id")),
                @JoinColumnOrFormula(formula = @JoinFormula(referencedColumnName = "tenant_id", value = "tenant_id"))
        })
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Hibernate 复合键和重叠字段 - 如何避免列重复 的相关文章

  • 将字符串转换为整数 JSP

    我是一个使用JSP的初学者 我想使用用户选择的最大范围显示递增整数的列表 输入 6 应显示以下内容 1号 number 2 number 3 number 4 number 5 number 6 输入 jsp
  • 哈希表中的下/上负载因子

    我要用java编写一个链式哈希集类 我知道负载系数是 M 容量 其中 M 是表中当前元素的数量 容量是表的大小 但是负载因子如何帮助我确定是否应该调整表大小并重新散列 此外 我在任何地方都找不到如何计算下 上负载系数 他们还需要吗 我希望这
  • 更改 JComboBox 中选择的颜色(选择后)

    我正在使用 Swing 编写 GUI 我有一个定制的写法JComboBox用一个ListCellRenderer and a BasicComboBoxEditor In my getListCellRendererComponent 方法
  • Spring:自定义验证器未被调用

    我正在查看有关 Spring 自定义验证器的其他问题 但不幸的是我无法用建议的答案解决我的问题 我的问题如下 我有一个实体 帐户 并且创建了一个自定义验证器 AccountValidator 我在控制器 RegisterController
  • 如果消费消息后出现错误,如何将消息保留在JMS消息队列中?

    我的场景是 我将消息发布到队列中 一旦消息被消耗 我将其发送到第三方中间件应用程序 如果该中间件应用程序关闭 那么我发布的消息就会被丢弃 如果中间件应用程序关闭 我不想丢失该消息 而是希望它处于暂停状态或在队列中等待 请建议 如何处理这种情
  • Android 构建 gradle 在特定设备上失败

    我面临一个奇怪的问题 当我编译我的应用程序以在 Android 7 0 的设备上运行它时 它可以工作 但是当我尝试为 Android 4 2 1 的设备进行编译时 它会失败并出现以下错误 错误 任务 app transformClasses
  • HttpUrlConnection addRequestProperty 方法不传递参数

    我有一些工作java代码 它执行以下操作 URL myUrl new URL http localhost 8080 webservice user username password password request x HttpURLC
  • 如何在没有JDK的情况下运行jcmd?

    我正在尝试弄清楚如何将 jcmd exe 删除到安装在客户端站点的 Windows 服务器上 以便我们可以解决堆和线程问题 不太想安装完整的 JDK 因为它会使环境变得复杂 jcmd exe 肯定需要运行 JDK 中的某些组件 但我无法确定
  • Java - 基类和子类中的 equals 方法

    我有一个简单的基类 后来由许多单独的类扩展 这些类可能会引入新的字段 但不一定 我在基类中定义了一个 equals 方法 但也为一些子类重写了该方法 可以在基类 子类中混合定义吗 就我而言 这是为了避免代码重复检查相同的字段 看一眼 实现
  • 尝试写入文件夹时出现“java.nio.file.AccessDeniedException”

    由于某种原因我不断得到java nio file AccessDeniedException每次我尝试使用 Tomcat 上的 java webapp 写入计算机上的文件夹时 此文件夹的权限设置为我的计算机 Windows 上的每个人的完全
  • 如何用JDT获取封闭的方法节点?

    当我有一个调用 bar 的方法 foo 时 如何从 MethodInspiration 节点 或方法中的任何语句 表达式 获取 foo AST 节点 例如 我需要从 b bar 知道 IMethod foo public void foo
  • 如何使用 jython 将参数传递给 java 中的 python 脚本

    我正在尝试使用 jython 在 java 中执行我的 python 脚本 重要的是我需要使用 jython 将命令行参数传递给我的脚本 例如myscript py arg1 arg2 arg3 这里有一个类似的问题 在 Java 中将参数
  • 相当于Android中的javax.swing.Timer

    有没有类似的东西javax swing Timer在安卓上 我知道如何创建自己的线程 但是有类似摆动计时器的东西吗 您可能正在寻找课程android os CountDownTimer http developer android com
  • 为什么我收到 NoClassDefFoundError: org/reactivestreams/Publisher

    Stream java import io reactivex public class Stream public static void main String args Observable just Howdy subscribe
  • CopyOnWriteArraySet.add 和 remove 的重写等于

    我有像下面这样的课程 class A Override public boolean equals Object other return true Class B extends A Class C extends A Override
  • 检索和设置 IntelliJ IDEA 插件开发的拆分窗口设置

    我正在编写一个 IntelliJ IDEA 插件 用于保存打开选项卡的会话 称为选项卡会话 https github com alp82 idea tabsession 这个问题是后续问题IntelliJ IDEA 插件开发 保存选项卡组
  • 如何安装 C++ 的 VOCE?

    我正在尝试安装 VOCE api 它是为 C 和 Java 构建的语音识别 API 这是我第二次使用外部 C 库 也是第一次使用 Java C api 语音链接 http voce sourceforge net http voce sou
  • 是否可以使用检测重新定义核心 JDK 类?

    我想重新定义字节码StackOverflowError构造函数 因此当堆栈溢出发生时我有一个 钩子 我想要做的就是在构造函数的开头插入对我选择的静态方法的单个方法调用 是否有可能做到这一点 您应该能够使用两种方法之一来完成此操作 除非在过去
  • 无法让远程 EJB 与 Wildfly 上的 EJB 客户端 API 配合使用

    我目前正在努力让远程 EJB 调用在 wildfly 8 x 和 9 x 上工作 详细来说 它是关于使用 EJB 客户端 API 方法从独立客户端应用程序 而不是从另一个应用程序服务器 进行远程调用 远程命名方法适用于我 但不适用于我的场景
  • 为什么Java HashMap的最大容量是1<<30而不是1<<31?

    Why is the maximum capacity of a Java HashMap 1 lt lt 30 and not 1 lt lt 31 even though the max value of an int is 231 1

随机推荐