I found a solution (try and error) - the EclipseLink documentation is not adequate on this point.
It is possible to use on INSERT:
WriteObjectQuery query = (WriteObjectQuery) event.getQuery();
DatabaseRecord rec = (DatabaseRecord) query.getModifyRow();
for (Object column : rec.keySet()) {
DatabaseField dbcol = (DatabaseField) column;
// get the column name with dbcol.getName()
// get the initial value with rec.getValues(dbcol).toString()
}
The UPDATE event on the original blog posting uses getObjectChangeSet() of class WriteObjectQuery. But the changes contain the field name of the Entity class, not the column name of the database.
I have read the mappings:
private String getDatabaseFieldMapping(DescriptorEvent event, String attribute) {
DatabaseMapping mapping = event.getDescriptor().getMappingForAttributeName(attribute);
return (mapping == null ? "<unknown>" : mapping.getField().getName());
}
and then I look for the attribute name from the ChangeRecord to get the column name:
WriteObjectQuery query = (WriteObjectQuery) event.getQuery();
for (ChangeRecord rec : query.getObjectChangeSet().getChanges()) {
if (rec instanceof DirectToFieldChangeRecord) {
DirectToFieldChangeRecord fieldChange = (DirectToFieldChangeRecord) rec;
// get the field name with getDatabaseFieldMapping(event, fieldChange.getAttribute())
// get the new value with fieldChange.getNewValue().toString()
}
}
The current user can be obtained with (no Dependency Injection on customizer classes!):
private EJBContext getContext() {
try {
InitialContext ic = new InitialContext();
return (EJBContext) ic.lookup("java:comp/EJBContext");
} catch (NamingException ex) {
throw new EJBException(ex);
}
}
@Entity
@Customizer(AuditHandler.class)
public class Test {
// ...
}
~André
[Updated on: Mon, 07 November 2011 15:38]
Report message to a moderator