I have a question for you hibernate gurus. Any help is appreciated. My question is whether there is any way to access the parameters from within the Hibernate Interceptor onPreparedStatement() call?
Here is why I need that behaviour. Solutions to my problem other than the one that prompted this question are also welcome.
I am trying to keep audit information in a separate set of tables from my primary tables. Changes can come from hibernate-enabled applications or from others. When the change comes from a web-server that is running a hibernate-enabled application, I need to include the login id of the currently logged in web user (not the application's single database user) with every change to the database tables. Thus every audit table has a nullable WEB_USER_ID column.
Because it is not just hibernate that generates audit information, database triggers are used to copy the information from the primary to the audit tables.
A hibernate interceptor reading a ThreadLocal variable solved most of the problem. It injected the logged in user into almost all the SQL.
Deleting an object looked like it would be a problem to audit since you can't add information about column values to a SQL delete command, but a solution was found. The onDelete() interceptor method was made to first do an update on the object with the logged in user being set so that the audit table has the full info on the delete, albeit spread across two audit rows.
Inserts and updates to the join tables of collections (which have no discrete mapped objects) likewise turned out to have a solution. The logged-in-user-id is added directly to the SQL inside the onPreparedStatement() method of the interceptor.
The combination of the two, though, is a problem. Deleting elements from a collection is proving unauditable. The reason is this:
- in many of the interceptor methods, we are working with mapped objects. But there are no mapped objects that represent the entries in a collection. So that leaves out onDelete(), onFlushDirty(), etc. Without replicating hibernate's mappings, we can't even use SQL directly from these methods because we don't know which table to use.
- in onPreparedStatement(), we are working with SQL. But the SQL uses parameters, and the parameters do not seem to be available for inspection inside the interceptor. That stops us from being able to do a separate update on the row of the join table that is about to be deleted after the onPreparedStatement() call is done. We have no idea which row to target.
Hence my question. How do I find out the values that would be placed into these parameters of the SQL statement? If there is currently no way to do it, is it possible that an access mechanism could be provided? A copied Array or Collection would be sufficient, to guarantee no monkeying around with the values. Or is there another way to accomplish what I am trying to do?
Thanks for any aid you can offer.
Hibernate version: 3.1.2
|