Hi,
I've got the following problem:
In an EJB3/JPA environment I want to set the id of a user who updates an entity on that entity. E. g. a class "Address" has a property "userId" which should be set whenever the address is updated.
Unfortunately I don't know whether the user has in fact changed the entity, so setting the userId before calling entityManager.merge(address) could cause an otherwise unchanged object to be written to the database because of the changed userId.
So I'm looking for a way to set this id only when the entity has been modified.
Currently the best way I've found is to let the business method (which knows the user) store the id in a singleton's ThreadLocal variable "userId", let it then call entityManager.merge(address) and provide a @PreUpdate callback in the Address entity. This callback is only executed when the entity was changed and so there I can retrieve the userId from the singleton and set it on the object's property.
But my gut feeling is that this is not a very "clean" solution. As far as I know the usage of ThreadLocal is discouraged in a managed environment because thread management is up to the application server and therefore not always predictable.
I've also tried using an interceptor by configuring it in persistence.xml. But because this is not thread-safe, I cannot pass on any session related information to it.
Another attempt was setting the userId from the business method and writing an interceptor which ignores this property on it's findDirty callback. But then I've got to do the whole dirty detection on my own which also does not seem to be a very elegant way to solve my problem. And it could get even more complicated when I have to deal with an object tree instead of just a single object.
Does anyone know a better way to do this than to use ThreadLocal? Or is ThreadLocal not as dangerous as I think?
Thanks,
Norbert
|