[英]How do I execute named queries from a JPA EntityListener?
I have a requirement to set a date_updated
value in my database for each row when that row is updated. 当该行更新时,我需要在数据库中为每一行设置一个
date_updated
值。 Let's call the entity that I'm working with Order
, which has a corresponding orders
table in the database. 我们将我正在使用的实体称为
Order
,该实体在数据库中具有一个对应的orders
表。
I've added the date_updated
column to the orders
table. 我已将
date_updated
列添加到orders
表。 So far, so good. 到现在为止还挺好。
The @Entity Order
object that I'm working with is provided by a third party. 我正在使用的
@Entity Order
对象由第三方提供。 I do not have the ability to modify the source code to add a field called dateUpdated
. 我没有能力修改源代码以添加一个名为
dateUpdated
的字段。 I have no requirement to map this value to the object anyway - the value is going to be used for business intelligence purposes only and does not need to be represented in the Java entity object. 无论如何,我都不需要将此值映射到对象-该值将仅用于商业智能目的,不需要在Java实体对象中表示。
My problem is this: I want to update the date_updated
column in the database to the current time each time an Order
object (and its corresponding database table row) is modified. 我的问题是:每次修改
Order
对象(及其对应的数据库表行)时,我都希望将数据库中的date_updated
列更新为当前时间。
Constraints: 约束:
My approach thus far has been to use a JPA EntityListener, defined in xml, similar to this: 到目前为止,我的方法是使用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>
My listener class looks like this: 我的侦听器类如下所示:
public class OrderJPAListener {
@PostPersist
@PostUpdate
public void recordDateUpdated(Order order) {
// do the update here
}
}
The problem I'm having is injecting any sort of persistence support (or anything at all, really) into my listener. 我遇到的问题是向侦听器注入任何形式的持久性支持(或什至没有任何东西)。 Because JPA loads the listener via its methods, I do not have access to any Spring beans in my listener class.
由于JPA通过其方法加载了侦听器,因此我无权访问侦听器类中的任何Spring Bean。
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? 如何将
EntityManager
(或任何Spring Bean)注入侦听器类中,以便可以执行命名查询来更新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?
如何将EntityManager(或任何Spring Bean)注入侦听器类中,以便可以执行命名查询来更新date_updated字段?
As noted above JPA 2.1 supports injecting managed beans to an Entity Listener via CDI. 如上所述,JPA 2.1支持通过CDI将托管bean注入到实体侦听器。 Whether or not Spring supports this I am not sure.
我不确定Spring是否支持这一点。 The folloiwng post proposes a Spring specific solution.
后续帖子提出了针对Spring的解决方案。
https://guylabs.ch/2014/02/22/autowiring-pring-beans-in-hibernate-jpa-entity-listeners/ https://guylabs.ch/2014/02/22/autowiring-pring-beans-in-hibernate-jpa-entity-listeners/
A possible alternative approach would be however to override the SQL generated by Hibernate on an update which is possible as detailed below. 但是,一种可能的替代方法是在更新时覆盖由Hibernate生成的SQL,这可能如下所述。
https://docs.jboss.org/hibernate/orm/3.6/reference/en-US/html/querysql.html#querysql-cud https://docs.jboss.org/hibernate/orm/3.6/reference/en-US/html/querysql.html#querysql-cud
This would be straightforward if you had the source as you would just need to add the @SQLUpdate annotation and tag on the additional date_update column. 如果您有源,这将很简单,因为您只需要在附加的date_update列上添加@SQLUpdate批注和标记即可。 As you don't however you would need to look at redefining the metadata for that Entity via an xml configuration file and defining the sql-update statement as outlined above:
但是,如您所愿,您将需要查看如何通过xml配置文件为该实体重新定义元数据,并定义sql-update语句,如上所述:
https://docs.jboss.org/hibernate/stable/annotations/reference/en/html/xml-overriding.html#xml-overriding-principles-entity https://docs.jboss.org/hibernate/stable/annotations/reference/en/html/xml-overriding.html#xml-overriding-principles-entity
Since JPA 2.1 Entity Listeners are CDI managed. 由于JPA 2.1实体侦听器是CDI管理的。 Have you tried using
@PersistenceUnit
annotation? 您是否尝试过使用
@PersistenceUnit
批注? Are you using JTA transaction type? 您正在使用JTA事务类型吗?
Otherwise you could use Persistence.createEntityManagerFactory
within the Listener class to retrieve the Persistence Context. 否则,您可以在Listener类中使用
Persistence.createEntityManagerFactory
来检索Persistence Context。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.