是否可以仅按需动态触发@PostLoad 方法的调用

Posted

技术标签:

【中文标题】是否可以仅按需动态触发@PostLoad 方法的调用【英文标题】:Is it possible to dynamically trigger calling of the @PostLoad method only on demand 【发布时间】:2010-07-19 11:32:53 【问题描述】:

环境:JBoss Seam、JPA、休眠

我们使用@PostLoad 注解来动态初始化@Entity 中的一些瞬态变量(有时这涉及到查找父实体来初始化状态——这是一个代价高昂的操作)。

但在某些情况下,我们不希望触发此@PostLoad,因为我们不会依赖瞬态变量。

有没有办法在加载后动态控制数据。

解决此问题的一种方法是仅按需调用此方法(即通过删除 @PostLoad 注释并手动调用此方法),但这也容易出错。

有没有其他方法可以解决这个问题。

【问题讨论】:

我认为您必须告诉我们您希望 Hibernate 如何知道何时触发 postLoad 以及何时不触发?基于实体的数据?如果您想要在读取数据之前执行以下操作: session.pleaseTriggerPostLoad(Foo.class) ,那么这与按需显式调用该方法没有什么不同。 能够将这样的标志发送到 JPA 查询会很有帮助,因为这些类型的状态更新程序在大型集合上运行时以及在急切的情况下会很昂贵。我从销售人员数据中​​收集帐户时遇到了类似的问题。将尝试自定义查询以获取要构建的 ID 列表,然后使用重载的构造函数加载对象,并设置阻止更新的 noExpiry 标志。 【参考方案1】:

但在某些情况下,我们不希望触发此@PostLoad,因为我们不会依赖瞬态变量。

创建两个实体,一个带有@PostLoad 和瞬态字段,一个“较轻”没有。

【讨论】:

你认为这可能吗?因为特定表只能有一个 @Entity 类,如果声明了 @PostLoad ,它将运行它。不确定我们是否可以有 2 个不同的实体类。请澄清 @Samuel 嗯...谁说一个特定的表只能有一个@Entity 类?您可以在同一张表上映射多个实体。现在,我并不是说这是理想的,但在你的情况下,这可能是一个解决方案。 我同意这可能是一种可能的解决方法,但它会涉及额外的类和可能更高的代码维护 @Samuel:实际上,当您无法使用投影时,将多个实体映射到同一张表上是 Hibernate 2 的常见做法(因此人们使用属性较少的“轻实体”/搜索屏幕的关联和详细屏幕的“胖版本”)。但你是对的,这会带来额外的维护。【参考方案2】:

在 java 中没有处理过这个问题,但在 kotlin + maven + spring 项目中遇到了类似的事情。

了解@PostLoad 的工作原理?

@PostLoad 在使用实体管理器方法获取数据后调用find()refresh() 操作被触发到数据库。

@PostLoad 触发失败的场景:

假设,一个parent 实体有这个@transient variable,它是使用@PostLoad 方法初始化的。此外,您有一个子实体映射到该父实体。

当您检索child 时,将加载查找并生成持久性上下文。当您尝试访问父内容时,会触发另一个查找。但这不会触发parent@PostLoad 方法,因为该操作是从现有上下文触发的。

这通常会引发未初始化的错误。

解决方案

在上述场景中,我真的不需要多个实体。据我所知,这种行为。我将为parent 创建一个实体类方法,以动态加载相应瞬态变量的内容,甚至为特殊场景设置一些默认值。并在转换器方法或用例所在的任何地方触发或管理此方法。

【讨论】:

以上是关于是否可以仅按需动态触发@PostLoad 方法的调用的主要内容,如果未能解决你的问题,请参考以下文章

iOS 按需资源 - 仅按需下载。调试

Hibernate @PostLoad 永远不会被调用

在 SQL Server 中获取触发器的调用者

如何在 iOS 上使用 Objective-C 触发按需 ***

如何使用堆栈跟踪或反射找到方法的调用者?

postLoad 实体与关联没有延迟加载?