Simple Auditing Example [message #1008667] |
Wed, 13 February 2013 14:18 |
|
Hello,
I build a webapplication using eclipselink with JPA running in a tomcat.
I build some simple audition that records the creator, change person and some timestamps. All in all my solution uses PersistenceListener and SessionEventListener like shown in this example:
http://wiki.eclipse.org/EclipseLink/Examples/JPA/Auditing#Example_AuditedObject_class
My Problem is, that sometimes the threadLocal.get() for the username is null.
Where is the best place to fill it?
I also tried to set additional properties when creation the entitymanager like this:
EntityManagerFactory factory = Persistence.createEntityManagerFactory("p1");
emProperties.put("eclipselink.tenant-id", mandator);
emProperties.put("username", username);
emProperties.put("mandator", mandator);
entityManger =factory.createEntityManager(emProperties);
((EntityManagerImpl)entityManger.getDelegate()).getUnitOfWork().setProperty("username", username);
((EntityManagerImpl)entityManger.getDelegate()).getUnitOfWork().setProperty("mandator", mandator);
((EntityManagerImpl)entityManger.getDelegate()).getSession().setProperty("username", username);
((EntityManagerImpl)entityManger.getDelegate()).getSession().setProperty("mandator", mandator);
((EntityManagerImpl)entityManger.getDelegate()).getServerSession().setProperty("username", username);
((EntityManagerImpl)entityManger.getDelegate()).getServerSession().setProperty("mandator", mandator);
and tried to read them in the EntityListener and SessionListener like this:
public class PersistenceListener implements SessionCustomizer {
public PersistenceListener() {
}
private static InheritableThreadLocal<TransactionInfo> info = new InheritableThreadLocal<TransactionInfo>();
public static InheritableThreadLocal<TransactionInfo> getInfo() {
return info;
}
public static void setInfo(InheritableThreadLocal<TransactionInfo> info) {
PersistenceListener.info = info;
}
@PreUpdate
void onPreUpdate(DBObject object) {
object.setChangeDate(info.get().getTransactionTime());
object.setChangePerson(info.get().getUsername());
}
@PrePersist
void onPrePersist(DBObject object) {
object.setChangeDate(info.get().getTransactionTime());
object.setChangePerson(info.get().getUsername());
object.setCreationDate(info.get().getTransactionTime());
object.setCreationPerson(info.get().getUsername());
object.setMandator(info.get().getMandator());
}
@PostPersist
void onPostPersist(DBObject object) {
}
@PostLoad
void onPostLoad(DBObject object) {
}
@PostUpdate
void onPostUpdate(DBObject object) {
object.setChangeDate(info.get().getTransactionTime());
object.setChangePerson(info.get().getUsername());
object.setCreationDate(info.get().getTransactionTime());
object.setCreationPerson(info.get().getUsername());
}
@PreRemove
void onPreRemove(DBObject object) {
}
@PostRemove
void onPostRemove(DBObject object) {
}
private void createTransactionInfo(SessionEvent arg0) {
}
@Override
public void customize(Session arg0) throws Exception {
String username = null;
String mandator = null;
if (ClientSession.class.isAssignableFrom(arg0.getClass())) {
username = (String) ((ClientSession) arg0).getProperty("username");
mandator = (String) ((ClientSession) arg0).getProperty("mandator");
}
else if (ServerSession.class.isAssignableFrom(arg0.getClass())) {
username = (String) ((ServerSession) arg0).getProperty("username");
mandator = (String) ((ServerSession) arg0).getProperty("mandator");
}
if (getInfo().get() == null && (username == null || mandator == null)){
throw new RuntimeException("Something wicked happened in auditing!");
}
getInfo().set(new TransactionInfo(username, Calendar.getInstance(), mandator));
}
}
But in the ServerSession the properties are null.
I guess there must be simple solution to pass the user who created the entitymanager instance to the EntityListenr / SessionCustomizer.
In Hibernate I would add an Interceptor to the session created by the SessionFactory holding this data.
I'd be very happy about some hints...no ideas left so far.
Thank you
[Updated on: Wed, 13 February 2013 16:38] Report message to a moderator
|
|
|
|
Re: Simple Auditing Example [message #1008996 is a reply to message #1008711] |
Thu, 14 February 2013 09:15 |
|
Well, I now wrote a wrapper class around the entitymanger with has a persist(DBObject object); Method that writes the auditing information to a threadlocal located in the class DBObject, which is a superclass of all entitites. This seems to work.
Anyway I would be glad if someone did this similar and has good experiences.
|
|
|
Powered by
FUDForum. Page generated in 0.01930 seconds