【问题标题】:How do I execute named queries from a JPA EntityListener?如何从 JPA EntityListener 执行命名查询?
【发布时间】:2016-04-19 04:23:12
【问题描述】:

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

我已将date_updated 列添加到orders 表中。到目前为止,一切顺利。

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

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

约束:

  • 我们正在使用 Oracle、Spring、JPA 和 Hibernate
  • 我无法使用 Oracle 触发器来更新值。我们使用的数据库复制技术会阻止我们使用触发器。

到目前为止,我的方法是使用 JPA EntityListener,在 xml 中定义,类似于:

<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 字段?

【问题讨论】:

    标签: spring oracle hibernate jpa entitylisteners


    【解决方案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

    【讨论】:

    • 我最终采用了类似于 guylabs.ch 解决方案的方法,使用 Spring 自动装配现有实例的能力。事实证明,Spring 足够聪明,可以自动装配带有 @PersistenceUnit 注释的字段。
    【解决方案2】:

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

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-01-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-02-15
      • 1970-01-01
      相关资源
      最近更新 更多