如何从 JPA EntityListener 执行命名查询?
How do I execute named queries from a JPA EntityListener?
我需要在我的数据库中为每行更新时设置一个 date_updated
值。让我们调用我正在使用的实体 Order
,它在数据库中有相应的 orders
table。
我已将 date_updated
列添加到 orders
table。到目前为止,还不错。
我正在使用的 @Entity Order
对象是由第三方提供的。我没有能力修改源代码来添加一个名为 dateUpdated
的字段。无论如何我都不需要将此值映射到对象 - 该值将仅用于商业智能目的,不需要在 Java 实体对象中表示。
我的问题是:每次 Order
对象(及其对应的数据库 table 行)更新时,我想将数据库中的 date_updated
列更新为当前时间已修改。
限制条件:
- 我们正在使用 Oracle、Spring、JPA 和 Hibernate
- 我无法使用 Oracle 触发器更新值。我们正在使用阻止我们使用触发器的数据库复制技术。
到目前为止,我的方法是使用 xml 中定义的 JPA EntityListener,类似于:
<entity-mappings xmlns="....">
<entity class="com.theirs.OrderImpl">
<entity-listeners>
<entity-listener class="com.mine.listener.OrderJPAListener" />
</entity-listeners>
</entity>
</entity-mappings>
我的听众 class 看起来像这样:
public class OrderJPAListener {
@PostPersist
@PostUpdate
public void recordDateUpdated(Order order) {
// do the update here
}
}
我遇到的问题是向我的侦听器注入任何类型的持久性支持(或任何东西,真的)。因为 JPA 通过其方法加载侦听器,所以我无法访问侦听器 class.
中的任何 Spring beans
如何将 EntityManager
(或任何 Spring bean)注入到我的侦听器 class 中,以便我可以执行命名查询来更新 date_updated
字段?
How do I go about injecting an EntityManager (or any Spring bean) into
my listener class so that I can execute a named query to update the
date_updated field?
如上所述,JPA 2.1 支持通过 CDI 将托管 bean 注入实体侦听器。 Spring 是否支持这个我不确定。以下post提出Spring具体解决方案
https://guylabs.ch/2014/02/22/autowiring-pring-beans-in-hibernate-jpa-entity-listeners/
然而,一种可能的替代方法是覆盖 Hibernate 在更新时生成的 SQL,如下所述。
https://docs.jboss.org/hibernate/orm/3.6/reference/en-US/html/querysql.html#querysql-cud
如果您有源代码,这将很简单,因为您只需要在附加的 date_update 列上添加 @SQLUpdate 注释和标记。但是,如果您不这样做,则需要考虑通过 xml 配置文件重新定义该实体的元数据并定义 sql-update 语句,如上文所述:
由于 JPA 2.1 实体侦听器是 CDI 管理的。您是否尝试过使用 @PersistenceUnit
注释?您使用的是 JTA 事务类型吗?
否则,您可以在侦听器 class 中使用 Persistence.createEntityManagerFactory
来检索持久性上下文。
我需要在我的数据库中为每行更新时设置一个 date_updated
值。让我们调用我正在使用的实体 Order
,它在数据库中有相应的 orders
table。
我已将 date_updated
列添加到 orders
table。到目前为止,还不错。
我正在使用的 @Entity Order
对象是由第三方提供的。我没有能力修改源代码来添加一个名为 dateUpdated
的字段。无论如何我都不需要将此值映射到对象 - 该值将仅用于商业智能目的,不需要在 Java 实体对象中表示。
我的问题是:每次 Order
对象(及其对应的数据库 table 行)更新时,我想将数据库中的 date_updated
列更新为当前时间已修改。
限制条件:
- 我们正在使用 Oracle、Spring、JPA 和 Hibernate
- 我无法使用 Oracle 触发器更新值。我们正在使用阻止我们使用触发器的数据库复制技术。
到目前为止,我的方法是使用 xml 中定义的 JPA EntityListener,类似于:
<entity-mappings xmlns="....">
<entity class="com.theirs.OrderImpl">
<entity-listeners>
<entity-listener class="com.mine.listener.OrderJPAListener" />
</entity-listeners>
</entity>
</entity-mappings>
我的听众 class 看起来像这样:
public class OrderJPAListener {
@PostPersist
@PostUpdate
public void recordDateUpdated(Order order) {
// do the update here
}
}
我遇到的问题是向我的侦听器注入任何类型的持久性支持(或任何东西,真的)。因为 JPA 通过其方法加载侦听器,所以我无法访问侦听器 class.
中的任何 Spring beans如何将 EntityManager
(或任何 Spring bean)注入到我的侦听器 class 中,以便我可以执行命名查询来更新 date_updated
字段?
How do I go about injecting an EntityManager (or any Spring bean) into my listener class so that I can execute a named query to update the date_updated field?
如上所述,JPA 2.1 支持通过 CDI 将托管 bean 注入实体侦听器。 Spring 是否支持这个我不确定。以下post提出Spring具体解决方案
https://guylabs.ch/2014/02/22/autowiring-pring-beans-in-hibernate-jpa-entity-listeners/
然而,一种可能的替代方法是覆盖 Hibernate 在更新时生成的 SQL,如下所述。
https://docs.jboss.org/hibernate/orm/3.6/reference/en-US/html/querysql.html#querysql-cud
如果您有源代码,这将很简单,因为您只需要在附加的 date_update 列上添加 @SQLUpdate 注释和标记。但是,如果您不这样做,则需要考虑通过 xml 配置文件重新定义该实体的元数据并定义 sql-update 语句,如上文所述:
由于 JPA 2.1 实体侦听器是 CDI 管理的。您是否尝试过使用 @PersistenceUnit
注释?您使用的是 JTA 事务类型吗?
否则,您可以在侦听器 class 中使用 Persistence.createEntityManagerFactory
来检索持久性上下文。