How to audit JPA without Hibernate Envers

André picture André · Oct 13, 2011 · Viewed 8.3k times · Source

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!

Answer

James picture James · Oct 13, 2011

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.