繁体   English   中英

如何从JPA EntityListener执行命名查询?

[英]How do I execute named queries from a JPA EntityListener?

当该行更新时,我需要在数据库中为每一行设置一个date_updated值。 我们将我正在使用的实体称为Order ,该实体在数据库中具有一个对应的orders表。

我已将date_updated列添加到orders表。 到现在为止还挺好。

我正在使用的@Entity Order对象由第三方提供。 我没有能力修改源代码以添加一个名为dateUpdated的字段。 无论如何,我都不需要将此值映射到对象-该值将仅用于商业智能目的,不需要在Java实体对象中表示。

我的问题是:每次修改Order对象(及其对应的数据库表行)时,我都希望将数据库中的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>

我的侦听器类如下所示:

public class OrderJPAListener { 

  @PostPersist
  @PostUpdate
  public void recordDateUpdated(Order order) {
    // do the update here
  }
}

我遇到的问题是向侦听器注入任何形式的持久性支持(或什至没有任何东西)。 由于JPA通过其方法加载了侦听器,因此我无权访问侦听器类中的任何Spring Bean。

如何将EntityManager (或任何Spring Bean)注入侦听器类中,以便可以执行命名查询来更新date_updated字段?

如何将EntityManager(或任何Spring Bean)注入侦听器类中,以便可以执行命名查询来更新date_updated字段?

如上所述,JPA 2.1支持通过CDI将托管bean注入到实体侦听器。 我不确定Spring是否支持这一点。 后续帖子提出了针对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语句,如上所述:

https://docs.jboss.org/hibernate/stable/annotations/reference/en/html/xml-overriding.html#xml-overriding-principles-entity

由于JPA 2.1实体侦听器是CDI管理的。 您是否尝试过使用@PersistenceUnit批注? 您正在使用JTA事务类型吗?

否则,您可以在Listener类中使用Persistence.createEntityManagerFactory来检索Persistence Context。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM