I need to make an audit module to my Java Web App. I use EclipseLink, not Hibernate (can't use Envers). I searched a lot some way to get the SQL or JPQL that JPA is executing, so I could log something like this:
System.out.println("User " + user + " from " + ip_address + " executed " + jpa_statement + " at " + new Date());
Actually, I'll save this info into a history database's table. So I can easily retrieve this info any time I want. That's why "SHOW SQL" parameters are not enough to me. I really need the SQL string, so I can manipulate it at my source code.
I found at JPA spec the EntityListener feature and thought it was the perfect place to put my logging code. For example, the postUpdate method could log the time the object was updated. But my problem is that I can't have the SQL the was executed.
Here is an example of what I mean:
public class AuditListener {
@PostUpdate
public void postUpdate(Object object) {
User user = (User)FacesContext.getCurrentInstance().getExternalContext().getSessionMap().get("user");
String ip_address = (User)FacesContext.getCurrentInstance().getExternalContext().getSessionMap().get("ip_address");
String jpa_statement = object.getSQL();
System.out.println("User " + user + " from " + ip_address + " executed " + jpa_statement + " at " + new Date());
}
}
But "object.getSQL()" doesn't exists. So how can I get the SQL statement?
If anyone could point me into the right direction, I would appreciate!
EclipseLink has full support for history tracking.
See, http://wiki.eclipse.org/EclipseLink/Examples/JPA/History
JPA events do not contain what was changed, only the object.
EclipseLink also supports DesriptorEvents (see DescriptorEventListener) which also define a postUpdate but include an ObjectChangeSet that describe the changes, you also have the UpdateObjectQuery that contains the SQL and DatabaseRecord.