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

时间:2016-01-14 00:11:47

标签: spring oracle hibernate jpa entitylisteners

当更新该行时,我需要在数据库中为每一行设置date_updated值。让我们调用我使用Order的实体,该实体在数据库中有相应的orders表。

我已将date_updated列添加到orders表格中。到目前为止,非常好。

我与之合作的@Entity Order对象由第三方提供。我无法修改源代码以添加名为dateUpdated的字段。我无需将此值映射到对象 - 该值仅用于商业智能目的,不需要在Java实体对象中表示。

我的问题是这样的:我希望每次修改date_updated对象(及其相应的数据库表行)时,将数据库中的Order列更新为当前时间。

约束:

  • 我们正在使用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字段?

2 个答案:

答案 0 :(得分:1)

  

如何将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

答案 1 :(得分:1)

自JPA 2.1实体监听器受CDI管理。您是否尝试过使用@PersistenceUnit注释?您使用的是JTA交易类型吗?

否则,您可以在Listener类中使用Persistence.createEntityManagerFactory来检索持久性上下文。

相关问题