【问题标题】:Does JPA allow EntityListeners to perform JPA operations?JPA 是否允许 EntityListeners 执行 JPA 操作?
【发布时间】:2020-11-25 16:22:16
【问题描述】:

看起来至少 PreCreate JPA 2.1 Create entity within JPA EntityListener 应该是可能的

我想做的是更新托管 JPA 实体中的 @Transient 数据,并在 @PostPersist@PostUpdate 事件上将托管 JPA 实体发送到 Kafka。该操作将从另一个存储库进行读取以获取一条数据。

但是,当我做这样的事情时,我会得到一个 ConcurrentModificationException 刷新。

我现在的解决方法是执行 JOOQ 操作以从另一个表中获取我需要的数据。

我的问题是 JPA 是否允许这种操作(即这可能是 Hibernate 错误)或者根据规范实际上是非法的。

【问题讨论】:

  • 也许规范中的这一部分对您有帮助?以下规则适用于生命周期回调方法:通常,可移植应用程序的生命周期方法不应调用 EntityManager 或查询操作、访问其他实体实例或修改同一持久性上下文中的关系[46]。 [47] 生命周期回调方法可以修改调用它的实体的非关系状态。
  • 因此,唯一的方法是将数据实际放在其他地方并以非 JPA 方式查找。
  • 依赖 post persist/update 似乎很奇怪:如果数据来自 JPA,为什么不在读取实体时预先填充它?如果事务回滚怎么办?
  • 为什么不添加一个像 'need_kafka_update' 这样的布尔字段,在持久化和查询实体时将其设置为 true,并且在后台使用该字段 = true ?在数据更新的同一事务中直接连接远程调用并不是一个好主意 - Kafka 服务器可能不可用,并且您将在这种逻辑下获得持久异常。
  • @Chris 遗留代码...只是想稍微调整一下以完成某些工作。

标签: java hibernate jpa spring-data


【解决方案1】:

根据第 3.5.2 章(生命周期回调方法)中的JPA 2.1 Specification,适用某些规则。其中之一说:

一般来说,可移植应用程序的生命周期方法不应调用 EntityManager 或查询操作、访问其他实体实例或修改 相同的持久性上下文[46]。 [47] 生命周期回调方法可能会修改非关系 调用它的实体的状态。

根据您的问题描述,您尝试做的事情似乎违反了此规则。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-08-14
    • 2021-10-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多