I have a requirement to set a date_updated
value in my database for each row when that row is updated. Let's call the entity that I'm working with Order
, which has a corresponding orders
table in the database.
I've added the date_updated
column to the orders
table. So far, so good.
The @Entity Order
object that I'm working with is provided by a third party. I do not have the ability to modify the source code to add a field called 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.
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.
Constraints:
My approach thus far has been to use a JPA EntityListener, defined in xml, similar to this:
<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.
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?
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?
As noted above JPA 2.1 supports injecting managed beans to an Entity Listener via CDI. Whether or not Spring supports this I am not sure. The folloiwng post proposes a Spring specific solution.
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.
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. 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: