【问题标题】:Hibernate entities on the same database table for read and write在同一个数据库表上休眠实体以进行读取和写入
【发布时间】:2020-07-12 13:45:14
【问题描述】:

在我们的 Spring Boot 应用程序中,同一个表有两个实体。

@Entity
@Table(name = "TBL_DATA")
@Immutable
public class DataReadEntity {

   // getters only
   ...
   // specific @OneToMany and @OneToOne relations only present in this entity
}

@Entity
@Table(name = "TBL_DATA")
@DynamicUpdate
public class DataWriteEntity {

  // getters and setters
}

DataReadEntity 仅用于数据搜索,并且始终在单独的 API 中使用。 DataWriteEntity 用于获取整个对象并对其进行更新。

问题是当使用 JPA 标准 API 更新 DataWriteEntity 时,hibernate 仍然显示警告 SessionImpl - HHH000487: The query: [here goes update query] attempts to update an immutable entity: [TBL_DATA],更新成功。

所以问题是 - 我们应该删除 @Immutable 注释还是忽略此警告,因为它按预期工作?认为 DataReadEntity 永远不会用于更新操作(甚至没有实现 setter)。

Spring Boot 应用程序正在使用默认配置 - spring.jpa.open-in-view is enabled by default

【问题讨论】:

    标签: java database spring-boot hibernate jpa


    【解决方案1】:

    底层数据库实体是可变的,但您希望同一个表有两个实体表示。但是hibernate知道它更新了哪个表并且很困惑,因为它在一个地方说它是不可变的。

    我不会因为文档中的这一点而忽略警告。它可能已经默默地忽略了对DataWriteEntity 的更新,即使没有,也可能在您有更新版本时发生。

    应用程序可能不会更新不可变实体。对不可变实体的更新将被忽略,但不会引发异常。 @Immutable 只能用于根实体。

    • 为什么不在数据库中为TBL_DATA 创建一个view,并将其作为表名提供给DataReadEntity 并保留@Immutable?所以hibernate很困惑,你也不会收到警告,也不需要担心版本更改时的意外行为?

    • 我也会警告不要删除@Immutable,因为如果你删除它,如果该api的用户出于其他目的故意修改该字段,认为它对数据库没有影响,但现在没有@Immutable所以休眠将通过脏检查传播更改。

    参考

    https://docs.jboss.org/hibernate/orm/5.2/javadocs/org/hibernate/annotations/Immutable.html

    【讨论】:

    • 谢谢。 View 可能有效,但我认为这是一种开销,如果我们需要更多数据,不方便扩展。关于其他命题-我写道,所有更新都可以正常工作(如果不是,将来会对其进行测试),并且读取实体仅用于特定用途。如果我们开始使用除 JPA 标准 API 之外的其他工具,可能会出现问题,这就是我想澄清的。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-11-28
    • 1970-01-01
    • 2012-08-05
    • 1970-01-01
    • 1970-01-01
    • 2015-10-19
    相关资源
    最近更新 更多