Re: Audit log with OpenJPA

2011-08-05 Thread Bengt Rodehav
Pinaki,

I've been on vacation again for a week which is why I'm late replying.

I think there must be a way to get hold of the original object since
that's the object I need to audit log. An unmanaged POJO is fine for my
purposes since I just want to serialize it. I will then persist it to a
separate audit log table using JPA as I showed before.

Just providing the dirty fields is not enough for most people's audit
logging requirements (in my opinon...).

It seems to me there are two main routes to go here:

a) Provide the plumbing necessary for developers to roll their own audit
log. Then the following is needed:
  - Access to the current and previous versions of the POJO (since I want to
log the whole previous version)
  - Information about what fields are dirty (if you only want to log what
has been changed)
  - Support for creating new persistent entities in the life cycle callback.
Ideally using the same entity manager. At least it must be possible to use
the same transaction otherwise the audit log will not be reliable.

b) Provide audit logging capabilities out-of-the-box. I think this is what
Envers does. The implementation details are hidden but the developer is
given an audit logging API to use. I would of course like to configure the
audit logging more than what is possible in Envers. E g I would perhaps like
the possibility to serialize my entities instead. Also, more options
regarding what fields to log would be nice.

These two routes need not be mutually exclusive. Like I said, if OpenJPA
supported something like Envers, that would probably be good enough for me.
If not, then I just need the necessary plumbing support to roll my own audit
logging with OpenJPA. But I need to know that I'm not using implementation
details that might change in the next version of OpenJPA.

/Bengt

2011/8/2 Pinaki Poddar ppod...@apache.org

 Hi Bengt,
  It is possible (with some effort :) to offer a different POJO y that holds
 the original state of a managed POJO x *when* x entered a persistence
 context. But y can not be managed by the same context, because x is already
 present in that context. So y will be essentially an unmanaged (not even
 detached) instance.

  Because of that conceptual dilemma, I went for the option of offering only
 the dirty field values. It is also possible to offer all field values.

 -
 Pinaki Poddar
 Chair, Apache OpenJPA Project
 --
 View this message in context:
 http://openjpa.208410.n2.nabble.com/Audit-log-with-OpenJPA-tp6557932p6645998.html
 Sent from the OpenJPA Users mailing list archive at Nabble.com.



Re: Audit log with OpenJPA

2011-08-02 Thread Pinaki Poddar
Hi Bengt,
  It is possible (with some effort :) to offer a different POJO y that holds
the original state of a managed POJO x *when* x entered a persistence
context. But y can not be managed by the same context, because x is already
present in that context. So y will be essentially an unmanaged (not even
detached) instance. 

  Because of that conceptual dilemma, I went for the option of offering only
the dirty field values. It is also possible to offer all field values. 

-
Pinaki Poddar
Chair, Apache OpenJPA Project
--
View this message in context: 
http://openjpa.208410.n2.nabble.com/Audit-log-with-OpenJPA-tp6557932p6645998.html
Sent from the OpenJPA Users mailing list archive at Nabble.com.


Re: Audit log with OpenJPA

2011-07-29 Thread pif
perhaps http://jpasecurity.sourceforge.net/
can help you to control access as JPA xxtension, but it's more for security
auditing than just logging

regards
Frank

--
View this message in context: 
http://openjpa.208410.n2.nabble.com/Audit-log-with-OpenJPA-tp6557932p6632956.html
Sent from the OpenJPA Users mailing list archive at Nabble.com.


Re: Audit log with OpenJPA

2011-07-29 Thread Bengt Rodehav
Interesting - will definitely take a look.

/Bengt
Den 29 jul 2011 19:24 skrev pif frank.pien...@googlemail.com:
 perhaps http://jpasecurity.sourceforge.net/
 can help you to control access as JPA xxtension, but it's more for
security
 auditing than just logging

 regards
 Frank

 --
 View this message in context:
http://openjpa.208410.n2.nabble.com/Audit-log-with-OpenJPA-tp6557932p6632956.html
 Sent from the OpenJPA Users mailing list archive at Nabble.com.


Re: Audit log with OpenJPA

2011-07-27 Thread Mark Struberg
Hi!

I've now looked at your test code and I'm not sure if it really is expected to 
work.
The JPA spec imo isn't very clear about  exactly _when_ the @PreUpdate gets 
called.

From the JPA-2.0 spec:
The PreUpdate and PostUpdate callbacks occur before and after the database 
update operations to entity data respectively. These database operations may 
occur at the time the entity state is updated or they may occur at the time 
state is flushed to the database (which may be at the end of the transaction).
Note that it is implementation-dependent as to whether PreUpdate and PostUpdate 
call- backs occur when an entity is persisted and subsequently modified in a 
single transaction or when an entity is modified and subsequently removed 
within a single transaction. Portable applications should not rely on such 
behavior.

It also doesn't say whether it will get called if the flush is performed for 
getting reproducible selects, etc.

Also the term 'entity data' caused a lot discussions already. What happens with 
a  EllementCollection or a CascadeType.PERSIST 1:n which is stored in your 
class? This obviously will render data in a different table. So is this covered 
by 'entity data'  or not?

There are lots of details in the JPA spec and not everything works as expected 
once you leave the simple samples and touch more complicated areas like lazy 
loading, fetch groups, detached entities, etc… You should for example try to 
close your EntityManager in your test (forces a detach) and then create a new 
one afterwards.

Of course you are relying on OpenJPA specific code, so you can argue that you 
don't need portability to other JPA providers at all. But still: it's not even 
guaranteed within OpenJPA that such subtle behavior will not change.
I'm also not sure if it's allowed to create a new entity within the same 
EntityManager while it is getting committed. I remember that I tried that and 
got an Exception because you cannot modify the EM while it is in the process of 
getting committed. But not 100% sure yet (grey cells refuse to find the 
paragraph in the docs) - Pinaki, you know what I mean and can shed a light on 
it? txs!

Of course it imo IS doable with OpenJPA, but it's definitely not a straight way 
;)
The StateManager code needs a bit of tweaking anyway. You could take a look at 
OPENJPA-1873 to get an idea about it ;)
I've already debugged into the StateManager stuff a big time and am ready to 
help out once we know how we'd like to solve this. 

LieGrue,
strub

--- On Tue, 7/26/11, Bengt Rodehav be...@rodehav.com wrote:

 From: Bengt Rodehav be...@rodehav.com
 Subject: Re: Audit log with OpenJPA
 To: users@openjpa.apache.org
 Date: Tuesday, July 26, 2011, 11:35 PM
 Yes, you're right Pinaki.
 
 I've attached a test case to the JIRA now. I'm very
 interested in your
 verdict...
 
 /Bengt
 
 2011/7/26 Pinaki Poddar ppod...@apache.org
 
  Hi Bengt,
   This thread has grown too lengthy for me to find
 where was the @PreUpdate
  code.
  For better convergence, please create a JUnit test and
 post it to
  OPENJPA-2030 [1]
 
 
  [1] https://issues.apache.org/jira/browse/OPENJPA-2030
 
  -
  Pinaki Poddar
  Chair, Apache OpenJPA Project
  --
  View this message in context:
  http://openjpa.208410.n2.nabble.com/Audit-log-with-OpenJPA-tp6557932p6623086.html
  Sent from the OpenJPA Users mailing list archive at
 Nabble.com.
 



Re: Audit log with OpenJPA

2011-07-27 Thread Bengt Rodehav
Hello Pinaki,

Thanks for looking into this. What you are suggesting seems useful and it
would be really nice if this functionality is supported in the future.
However, I can't see how it directly solves my problem. What I'm trying to
do in my audit log is to save a serialized form of my entity - the whole
entity and not just the dirty fields. My intention was to use JSON (with
Gson) for this. I'm sure there are many different approaches to an audit log
(as can be seen from this long conversation) but my rationale is:

I want an easy way to show the user exactly what a previous version looked
like. Either I save the complete previous version or I have to reconstruct
it when showing it to the user. The former seems easier. Furthermore, audit
logging is used for rather static (as opposed to transactional data) which
means that there is no problem using up a few more bytes.

Clearly indicating what fields were changed is a bonus. If I could save both
a serialization of the previous version and some metadata indicating what
fields were changed that would be perfect. I would probably have to drop
JSON and go for XML instead then.

The API extension you're proposing will give me information about the dirty
fields but I can't clearly see how I can create a serialization of the
previous version for the entity.

/Bengt
2011/7/27 Pinaki Poddar ppod...@apache.org

 Hi Bengt,
  I find that accessing the old state is possible using internal mechanics
 -- but could not find a way to do it from the current API unless I expose
 some internals. After a bit of deliberation, I am suggesting that we add
 the
 following method to SaveFieldManager.

/**
 * Gets the old values for the given list of fields provided they are
 dirty.
 * @param fields a list of field names. null implies all dirty fields.
 * @return a map of old values for each given field, if they are dirty.
 * The map values are a pair of objects in an array -- the 0-th element
 * is the old value and the 1-st element is the current value.
 */
public Maplt;String, Object[]gt; getOldValues(String...fields)

 I have tested your supplied classes with the classes you supplied.

 If you do not mind being in the bleeding edge, i.e. if you can consume
 OpenJPA nightly builds, then I will commit the changes.





 -
 Pinaki Poddar
 Chair, Apache OpenJPA Project
 --
 View this message in context:
 http://openjpa.208410.n2.nabble.com/Audit-log-with-OpenJPA-tp6557932p6624609.html
 Sent from the OpenJPA Users mailing list archive at Nabble.com.



Re: Audit log with OpenJPA

2011-07-26 Thread Pinaki Poddar
Hi Bengt,
  This thread has grown too lengthy for me to find where was the @PreUpdate
code. 
For better convergence, please create a JUnit test and post it to
OPENJPA-2030 [1]


[1] https://issues.apache.org/jira/browse/OPENJPA-2030 

-
Pinaki Poddar
Chair, Apache OpenJPA Project
--
View this message in context: 
http://openjpa.208410.n2.nabble.com/Audit-log-with-OpenJPA-tp6557932p6623086.html
Sent from the OpenJPA Users mailing list archive at Nabble.com.


Re: Audit log with OpenJPA

2011-07-26 Thread Bengt Rodehav
Yes, you're right Pinaki.

I've attached a test case to the JIRA now. I'm very interested in your
verdict...

/Bengt

2011/7/26 Pinaki Poddar ppod...@apache.org

 Hi Bengt,
  This thread has grown too lengthy for me to find where was the @PreUpdate
 code.
 For better convergence, please create a JUnit test and post it to
 OPENJPA-2030 [1]


 [1] https://issues.apache.org/jira/browse/OPENJPA-2030

 -
 Pinaki Poddar
 Chair, Apache OpenJPA Project
 --
 View this message in context:
 http://openjpa.208410.n2.nabble.com/Audit-log-with-OpenJPA-tp6557932p6623086.html
 Sent from the OpenJPA Users mailing list archive at Nabble.com.



Re: Audit log with OpenJPA

2011-07-26 Thread Pinaki Poddar
Hi Bengt,
  I find that accessing the old state is possible using internal mechanics
-- but could not find a way to do it from the current API unless I expose
some internals. After a bit of deliberation, I am suggesting that we add the
following method to SaveFieldManager.

/**
 * Gets the old values for the given list of fields provided they are
dirty.
 * @param fields a list of field names. null implies all dirty fields.
 * @return a map of old values for each given field, if they are dirty.
 * The map values are a pair of objects in an array -- the 0-th element 
 * is the old value and the 1-st element is the current value.
 */
public Maplt;String, Object[]gt; getOldValues(String...fields)

I have tested your supplied classes with the classes you supplied.

If you do not mind being in the bleeding edge, i.e. if you can consume
OpenJPA nightly builds, then I will commit the changes.

 



-
Pinaki Poddar
Chair, Apache OpenJPA Project
--
View this message in context: 
http://openjpa.208410.n2.nabble.com/Audit-log-with-OpenJPA-tp6557932p6624609.html
Sent from the OpenJPA Users mailing list archive at Nabble.com.


Re: Audit log with OpenJPA

2011-07-25 Thread Bengt Rodehav
Hello again Mark and Pinaki,

I've tried with the properties you mentioned Mark (and the one you mentioned
in your blog Pinaki). B ut I can see no difference. I also switched from
OpenJPA 2.0.1 to 2.1.1 but still no difference. My persistence.xml looks
like this:

*?xml version=1.0 encoding=UTF-8?*
*persistence xmlns=http://java.sun.com/xml/ns/persistence; xmlns:xsi=
http://www.w3.org/2001/XMLSchema-instance*
*  xsi:schemaLocation=http://java.sun.com/xml/ns/persistence
http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd*
*  version=2.0*
*  persistence-unit name=maiaTestPU transaction-type=RESOURCE_LOCAL*
*
providerorg.apache.openjpa.persistence.PersistenceProviderImpl/provider*
*classse.digia.maia.core.bu.domain.BusinessUnit/class*
*classse.digia.maia.common.persistence.EntityBase/class*
*classse.digia.maia.common.security.domain.User/class*
*classse.digia.maia.common.auditlog.domain.AuditLogEntry/class*
*exclude-unlisted-classestrue/exclude-unlisted-classes*
*validation-modeNONE/validation-mode*
*properties*
*  property name=openjpa.RestoreState value=all /*
*  property name=openjpa.DetachState
value=loaded(DetachedStateField=true) /*
*  property name=openjpa.Compatibility
value=IgnoreDetachedStateFieldForProxySerialization=true /*
*  property name=javax.persistence.jdbc.password value=root /*
*  property name=javax.persistence.jdbc.user value=root /*
*  property name=javax.persistence.jdbc.driver
value=com.mysql.jdbc.Driver /*
*  property name=javax.persistence.jdbc.url
value=jdbc:mysql://localhost:3306/maia?createDatabaseIfNotExist=true /*
*  property name=openjpa.jdbc.SynchronizeMappings
value=buildSchema(ForeignKeys=true) /*
*  property name=openjpa.jdbc.DBDictionary
value=org.apache.openjpa.jdbc.sql.MySQLDictionary /*
*  property name=openjpa.jdbc.UpdateManager value=operation-order
/*
*  property name=openjpa.Log value=DefaultLevel=WARN, Tool=INFO /*
*/properties*
*  /persistence-unit*
*/persistence*

My JUnit test case look like this:

*...*
*// Create the business unit*
*cEntityManager.getTransaction().begin();*
*BusinessUnit bu = createPersistentBusinessUnit(Created, Created
department);*
*cEntityManager.getTransaction().commit();*
*
*
*// Update the business unit*
*cEntityManager.getTransaction().begin();*
*BusinessUnit bu2 = cEntityManager.find(BusinessUnit.class, bu.getId());
*
*bu2.setShortName(Updated);*
*bu2.setName(Updated too);*
*cEntityManager.merge(bu2);*
*cEntityManager.getTransaction().commit(); //  Throws an exception*
*
*
*// Verify business unit*
*BusinessUnit bu3 = cEntityManager.find(BusinessUnit.class, bu.getId());
*
*assertEquals(bu.getId(), bu3.getId());*
*assertEquals(bu.getShortName(), bu3.getShortName());*
*assertEquals(bu.getName(), bu3.getName());*

The @PreUpdate callback is as I mentioned in a previous post. The marked
line (with a comment) throws an exception. The reason is that mandatory
values are missing. Values that exist in the persisted entity (variable
bu) but are not updated. If I remove the audit logging from my @PreUpdate
method, the JUnit test case succeeds.

Any clues?

/Bengt


2011/7/21 Bengt Rodehav be...@rodehav.com

 I'm currently in Turkey on vacation but will try when I get back to Sweden.
 /Bengt
 Den 19 jul 2011 17:48 skrev Pinaki Poddar ppod...@apache.org:

  Hi Bengt,
  It is not obvious to me how DetachState related options will impact
  in-transaction entities. But I am interested to know the result of your
  experiment with the options Mark has suggested.
 
  I will recommend you make sure the following
  1. Enhance at build time
  2. Set openjpa.RestoreState=true
 
 
 
 
  -
  Pinaki Poddar
  Chair, Apache OpenJPA Project
  --
  View this message in context:
 http://openjpa.208410.n2.nabble.com/Audit-log-with-OpenJPA-tp6557932p6599036.html
  Sent from the OpenJPA Users mailing list archive at Nabble.com.



Re: Audit log with OpenJPA

2011-07-21 Thread Bengt Rodehav
I'm currently in Turkey on vacation but will try when I get back to Sweden.
/Bengt
Den 19 jul 2011 17:48 skrev Pinaki Poddar ppod...@apache.org:
 Hi Bengt,
 It is not obvious to me how DetachState related options will impact
 in-transaction entities. But I am interested to know the result of your
 experiment with the options Mark has suggested.

 I will recommend you make sure the following
 1. Enhance at build time
 2. Set openjpa.RestoreState=true




 -
 Pinaki Poddar
 Chair, Apache OpenJPA Project
 --
 View this message in context:
http://openjpa.208410.n2.nabble.com/Audit-log-with-OpenJPA-tp6557932p6599036.html
 Sent from the OpenJPA Users mailing list archive at Nabble.com.


Re: Audit log with OpenJPA

2011-07-19 Thread Bengt Rodehav
Thanks Mark,

I'll give it a try. However, it seems a bit shaky if this is not officially
supported by OpenJPA. Do you know if this will clearly be supported in the
future?

/Bengt
Den 17 jul 2011 02:45 skrev Mark Struberg strub...@yahoo.de:
 It does keep track, but you might need to experiment a bit with your
persistence.xml. In my case (doing lots of detached work), I needed the
following settings:

 property name=openjpa.DetachState
value=loaded(DetachedStateField=true)/
 property name=openjpa.Compatibility
value=IgnoreDetachedStateFieldForProxySerialization=true/

 Be aware that some of those settings radically change the way OpenJPA
works internally. But otherwise detached, merging, etc does not really work
as this area is pretty under-specced.
 I also remember that I needed to fix a few things to get the correct state
in OPENJPA-1873. Not sure how much of this patch got already committed (got
my time eaten up by a few other Apache projects lately).

 LieGrue,
 stru

 --- On Sat, 7/16/11, Bengt Rodehav be...@rodehav.com wrote:

 From: Bengt Rodehav be...@rodehav.com
 Subject: Re: Audit log with OpenJPA
 To: users@openjpa.apache.org
 Date: Saturday, July 16, 2011, 8:40 PM
 Did you have a suggestion regarding
 this Pinaki - or does OpenJPA only keep
 track of changed values - not the whole original object?

 /Bengt

 2011/7/15 Bengt Rodehav be...@rodehav.com

  I don't understand Pinaki.
 
  The this pointer is the current version of the
 object (the one that is
  about to be persisted) right? I want the previous
 version of the object. I
  have used your code from the blog (and added some of
 course) like this:
 
  *
 
  PersistenceCapable
 currentState = (PersistenceCapable) this;
 
  StateManagerImpl sm =
 (StateManagerImpl)
  currentState.pcGetStateManager();
 
  SaveFieldManager sfm =
 sm.getSaveFieldManager();
 
  PersistenceCapable
 oldState = sfm.getState();
 
  EntityBase old =
 (EntityBase) oldState;
 
  old = (EntityBase)
 oldState;
 
 
  AuditLogEntry entry =
 new AuditLogEntry();
 
 
entry.setSerializedState(cAuditLog.serialize(old));
 
 
entry.setEntityId(old.getId());
 
 
entry.setCreatedWhen(old.getCreatedWhen());
 
 
entry.setCreatedBy(old.getCreatedBy());
 
 
entry.setUpdatedWhen(old.getUpdatedWhen());
 
 
entry.setUpdatedBy(old.getUpdatedBy());
 
 
entry.setVersion(old.getVersion());
 
 
 
  EntityManager em =
 OpenJPAPersistence.getEntityManager(this);
 
  em.persist(entry);
 
 
  *
 
 
  cAuditLog is an object which uses Gson to serialize
 the object to a String.
 
  The problem is that only those fields that I have
 actually updated are
  initialized in the variable old. The rest of the
 fields are uninitialized.
  In my case I do not only want to save the changed
 fields but the whole
  object. How can I make sure that old is fully
 initialized?
 
  /Bengt
 
  2011/7/15 Pinaki Poddar ppod...@apache.org
 
  The whole object is *this* pointer on which you
 received the callback.
  You can safely cast it into PersistenceCapable and
 get to know all about
  its
  state.
 
  Please see the blog post -- it has some toy code.
 
  -
  Pinaki Poddar
  Chair, Apache OpenJPA Project
  --
  View this message in context:
 
http://openjpa.208410.n2.nabble.com/Audit-log-with-OpenJPA-tp6557932p6585154.html
  Sent from the OpenJPA Users mailing list archive
 at Nabble.com.
 
 
 



Re: Audit log with OpenJPA

2011-07-19 Thread Pinaki Poddar
Hi Bengt,
  It is not obvious to me how DetachState related options will impact
in-transaction entities. But I am interested to know the result of your
experiment with the options Mark has suggested.

  I will recommend you make sure the following
  1. Enhance at build time 
  2. Set openjpa.RestoreState=true

 
  

-
Pinaki Poddar
Chair, Apache OpenJPA Project
--
View this message in context: 
http://openjpa.208410.n2.nabble.com/Audit-log-with-OpenJPA-tp6557932p6599036.html
Sent from the OpenJPA Users mailing list archive at Nabble.com.


Re: Audit log with OpenJPA

2011-07-19 Thread Mark Struberg
Yes, I just mentioned it because in my case it made a _huge_ difference when 
working with previously detached entities which got em.merged().

I don't know the exact scenario, but since EntityManagers are not Serializable, 
there is detachment needed in a lot cases. At least if you need it also working 
in a cluster or load balancer scenario. 

LieGrue,
strub

--- On Tue, 7/19/11, Pinaki Poddar ppod...@apache.org wrote:

 From: Pinaki Poddar ppod...@apache.org
 Subject: Re: Audit log with OpenJPA
 To: users@openjpa.apache.org
 Date: Tuesday, July 19, 2011, 2:47 PM
 Hi Bengt,
   It is not obvious to me how DetachState related
 options will impact
 in-transaction entities. But I am interested to know the
 result of your
 experiment with the options Mark has suggested.
 
   I will recommend you make sure the following
   1. Enhance at build time 
   2. Set openjpa.RestoreState=true
 
  
   
 
 -
 Pinaki Poddar
 Chair, Apache OpenJPA Project
 --
 View this message in context: 
 http://openjpa.208410.n2.nabble.com/Audit-log-with-OpenJPA-tp6557932p6599036.html
 Sent from the OpenJPA Users mailing list archive at
 Nabble.com.



Re: Audit log with OpenJPA

2011-07-19 Thread Mark Struberg
Yes, I just mentioned it because in my case it made a _huge_ difference when 
working with previously detached entities which got em.merged().

I don't know the exact scenario, but since EntityManagers are not Serializable, 
there is detachment needed in a lot cases. At least if you need it also working 
in a cluster or load balancer scenario. 

LieGrue,
strub

--- On Tue, 7/19/11, Pinaki Poddar ppod...@apache.org wrote:

 From: Pinaki Poddar ppod...@apache.org
 Subject: Re: Audit log with OpenJPA
 To: users@openjpa.apache.org
 Date: Tuesday, July 19, 2011, 2:47 PM
 Hi Bengt,
   It is not obvious to me how DetachState related
 options will impact
 in-transaction entities. But I am interested to know the
 result of your
 experiment with the options Mark has suggested.
 
   I will recommend you make sure the following
   1. Enhance at build time 
   2. Set openjpa.RestoreState=true
 
  
   
 
 -
 Pinaki Poddar
 Chair, Apache OpenJPA Project
 --
 View this message in context: 
 http://openjpa.208410.n2.nabble.com/Audit-log-with-OpenJPA-tp6557932p6599036.html
 Sent from the OpenJPA Users mailing list archive at
 Nabble.com.



Re: Audit log with OpenJPA

2011-07-18 Thread Pinaki Poddar
Bengt,
  I had been busy with other things not to address your question.
  Did you read the very two last lines of the blog? They have the right
configuration options required for the restorable state. Let me know if
things do not work even after you have used those two directives. 

-
Pinaki Poddar
Chair, Apache OpenJPA Project
--
View this message in context: 
http://openjpa.208410.n2.nabble.com/Audit-log-with-OpenJPA-tp6557932p6594830.html
Sent from the OpenJPA Users mailing list archive at Nabble.com.


Re: Audit log with OpenJPA

2011-07-16 Thread Bengt Rodehav
Did you have a suggestion regarding this Pinaki - or does OpenJPA only keep
track of changed values - not the whole original object?

/Bengt

2011/7/15 Bengt Rodehav be...@rodehav.com

 I don't understand Pinaki.

 The this pointer is the current version of the object (the one that is
 about to be persisted) right? I want the previous version of the object. I
 have used your code from the blog (and added some of course) like this:

 *

 PersistenceCapable currentState = (PersistenceCapable) this;

 StateManagerImpl sm = (StateManagerImpl)
 currentState.pcGetStateManager();

 SaveFieldManager sfm = sm.getSaveFieldManager();

 PersistenceCapable oldState = sfm.getState();

 EntityBase old = (EntityBase) oldState;

 old = (EntityBase) oldState;


 AuditLogEntry entry = new AuditLogEntry();

 entry.setSerializedState(cAuditLog.serialize(old));

 entry.setEntityId(old.getId());

 entry.setCreatedWhen(old.getCreatedWhen());

 entry.setCreatedBy(old.getCreatedBy());

 entry.setUpdatedWhen(old.getUpdatedWhen());

 entry.setUpdatedBy(old.getUpdatedBy());

 entry.setVersion(old.getVersion());



 EntityManager em = OpenJPAPersistence.getEntityManager(this);

 em.persist(entry);


 *


 cAuditLog is an object which uses Gson to serialize the object to a String.

 The problem is that only those fields that I have actually updated are
 initialized in the variable old. The rest of the fields are uninitialized.
 In my case I do not only want to save the changed fields but the whole
 object. How can I make sure that old is fully initialized?

 /Bengt

 2011/7/15 Pinaki Poddar ppod...@apache.org

 The whole object is *this* pointer on which you received the callback.
 You can safely cast it into PersistenceCapable and get to know all about
 its
 state.

 Please see the blog post -- it has some toy code.

 -
 Pinaki Poddar
 Chair, Apache OpenJPA Project
 --
 View this message in context:
 http://openjpa.208410.n2.nabble.com/Audit-log-with-OpenJPA-tp6557932p6585154.html
 Sent from the OpenJPA Users mailing list archive at Nabble.com.





Re: Audit log with OpenJPA

2011-07-16 Thread Mark Struberg
It does keep track, but you might need to experiment a bit with your 
persistence.xml. In my case (doing lots of detached work), I needed the 
following settings:

property name=openjpa.DetachState 
value=loaded(DetachedStateField=true)/
property name=openjpa.Compatibility 
value=IgnoreDetachedStateFieldForProxySerialization=true/

Be aware that some of those settings radically change the way OpenJPA works 
internally. But otherwise detached, merging, etc does not really work as this 
area is pretty under-specced.
I also remember that I needed to fix a few things to get the correct state in 
OPENJPA-1873. Not sure how much of this patch got already committed (got my 
time eaten up by a few other Apache projects lately).

LieGrue,
stru 

--- On Sat, 7/16/11, Bengt Rodehav be...@rodehav.com wrote:

 From: Bengt Rodehav be...@rodehav.com
 Subject: Re: Audit log with OpenJPA
 To: users@openjpa.apache.org
 Date: Saturday, July 16, 2011, 8:40 PM
 Did you have a suggestion regarding
 this Pinaki - or does OpenJPA only keep
 track of changed values - not the whole original object?
 
 /Bengt
 
 2011/7/15 Bengt Rodehav be...@rodehav.com
 
  I don't understand Pinaki.
 
  The this pointer is the current version of the
 object (the one that is
  about to be persisted) right? I want the previous
 version of the object. I
  have used your code from the blog (and added some of
 course) like this:
 
  *
 
      PersistenceCapable
 currentState = (PersistenceCapable) this;
 
      StateManagerImpl sm =
 (StateManagerImpl)
  currentState.pcGetStateManager();
 
      SaveFieldManager sfm =
 sm.getSaveFieldManager();
 
      PersistenceCapable
 oldState = sfm.getState();
 
      EntityBase old =
 (EntityBase) oldState;
 
      old = (EntityBase)
 oldState;
 
 
      AuditLogEntry entry =
 new AuditLogEntry();
 
  
    entry.setSerializedState(cAuditLog.serialize(old));
 
  
    entry.setEntityId(old.getId());
 
  
    entry.setCreatedWhen(old.getCreatedWhen());
 
  
    entry.setCreatedBy(old.getCreatedBy());
 
  
    entry.setUpdatedWhen(old.getUpdatedWhen());
 
  
    entry.setUpdatedBy(old.getUpdatedBy());
 
  
    entry.setVersion(old.getVersion());
 
 
 
      EntityManager em =
 OpenJPAPersistence.getEntityManager(this);
 
      em.persist(entry);
 
 
  *
 
 
  cAuditLog is an object which uses Gson to serialize
 the object to a String.
 
  The problem is that only those fields that I have
 actually updated are
  initialized in the variable old. The rest of the
 fields are uninitialized.
  In my case I do not only want to save the changed
 fields but the whole
  object. How can I make sure that old is fully
 initialized?
 
  /Bengt
 
  2011/7/15 Pinaki Poddar ppod...@apache.org
 
  The whole object is *this* pointer on which you
 received the callback.
  You can safely cast it into PersistenceCapable and
 get to know all about
  its
  state.
 
  Please see the blog post -- it has some toy code.
 
  -
  Pinaki Poddar
  Chair, Apache OpenJPA Project
  --
  View this message in context:
  http://openjpa.208410.n2.nabble.com/Audit-log-with-OpenJPA-tp6557932p6585154.html
  Sent from the OpenJPA Users mailing list archive
 at Nabble.com.
 
 
 



Re: Audit log with OpenJPA

2011-07-15 Thread Bengt Rodehav
I don't understand Pinaki.

The this pointer is the current version of the object (the one that is
about to be persisted) right? I want the previous version of the object. I
have used your code from the blog (and added some of course) like this:

*

 PersistenceCapable currentState = (PersistenceCapable) this;

 StateManagerImpl sm = (StateManagerImpl)
 currentState.pcGetStateManager();

 SaveFieldManager sfm = sm.getSaveFieldManager();

 PersistenceCapable oldState = sfm.getState();

 EntityBase old = (EntityBase) oldState;

 old = (EntityBase) oldState;


 AuditLogEntry entry = new AuditLogEntry();

 entry.setSerializedState(cAuditLog.serialize(old));

 entry.setEntityId(old.getId());

 entry.setCreatedWhen(old.getCreatedWhen());

 entry.setCreatedBy(old.getCreatedBy());

 entry.setUpdatedWhen(old.getUpdatedWhen());

 entry.setUpdatedBy(old.getUpdatedBy());

 entry.setVersion(old.getVersion());



 EntityManager em = OpenJPAPersistence.getEntityManager(this);

 em.persist(entry);


 *


cAuditLog is an object which uses Gson to serialize the object to a String.

The problem is that only those fields that I have actually updated are
initialized in the variable old. The rest of the fields are uninitialized.
In my case I do not only want to save the changed fields but the whole
object. How can I make sure that old is fully initialized?

/Bengt
2011/7/15 Pinaki Poddar ppod...@apache.org

 The whole object is *this* pointer on which you received the callback.
 You can safely cast it into PersistenceCapable and get to know all about
 its
 state.

 Please see the blog post -- it has some toy code.

 -
 Pinaki Poddar
 Chair, Apache OpenJPA Project
 --
 View this message in context:
 http://openjpa.208410.n2.nabble.com/Audit-log-with-OpenJPA-tp6557932p6585154.html
 Sent from the OpenJPA Users mailing list archive at Nabble.com.



Re: Audit log with OpenJPA

2011-07-14 Thread Bengt Rodehav
Hi again Jim,

2011/7/14 Jim Talbut jtal...@spudsoft.co.uk

 On 13/07/2011 21:14, Pinaki Poddar wrote:

 Yes. Any audit facility needs to have a snapshot of the entity when it
 entered a persistence context, so at @PreUpdate or at any other time
 points,
 it can figure out what has essentially been changed about that entity in a
 transaction. Now either one can build their own mechanics to store the
 original state of the entity or can use OpenJPA's own facility to access
 the
 original state. The blog article showed the later approach.

 I also went with using the OpenJPA stored version of the original object.
 There are a few niggles to getting that data that one has to work with, but
 I still think it's considerably less effort than building your own
 mechanism.

  Secondly, in my view, an audit facility should be orthogonal. The actual
 domain entity need not know that it is being audited. Thereby, the domain
 entity need not have an association or knowledge of an Audit object.

 I'd agree with that for a general purpose audit facility.
 In my case I don't even call it audit it's change tracking, and the
 change information is displayed alongside the entities in the most common
 cases.

  Thirdly, the audit facility should allow the audit information be stored
 in
 a separate database, in the same database or may even be logged in a file.
 That is to say that persistence of audit information should be decoupled
 from persistence of the domain objects.

 Again, true for a general purpose audit facility.
 If you want to be really secure the audit log should be sent directly to a
 printer :)


  If you intend to store audit information as a persistent entity in the
 same
 database as the domain entity, then the simple solution is something like
 this in a domain class:

   @PreUpdate
   public void audit() {
  Audit audit = new Audit();
   // now populate audit information
   //  some serious delta computation

   // Now get the entity manager that is managing this current
 domain
 object
   OpenJPAEntityManager em =
 OpenJPAPersistence.**getEntityManager(this);

   // And persist the audit information in the same transaction
  em.persist(audit);
   }


 I wonder if that bends the rules any more than my approach?


Exactly what I was thinking. Since you seem to be bending the rules in your
approach as well (creating new entities in the @PreUpdate), why not bend it
a little more? The benefit is that you can get the audit logging out of the
domain model (if you want to). Also, in my case, I have no use for the join
table between my entities so it feel nice to get rid of it...

Since neither of these approaches are supported by JPA but depends on the
implementation of OpenJPA, one might as well choose the most convenient one.
It'd be nice though if at least OpenJPA could officially support this kind
of mechanism since I think it's needed in real life anyway.

/Bengt


 Jim



Re: Audit log with OpenJPA

2011-07-14 Thread Pinaki Poddar
Jim,
  I was making generic statements about audit and was not meant to address
the specific approach you might have taken to suit your needs. I will take a
closer look at the approach you have come up with.

  About 'delta computation', however, I find OpenJPA provides strong feature
via its SavePointManager and restore facility. The advantage is that leaves
the callback listeners stateless. Also, the managed entity knows which
fields have been modified/dirtied -- which is essential to any delta
computation. 

Bengt,
   Good to know you have made it working.

Now the question/concern about spec-compliance what is permissible in
@PreUpdate

  a) JPA spec so far have discouraged entity modification in callbacks. 
Specifically,
JPA 2.0 spec does not allow access to EntityManager and modification of
existing relations. These restrictions stem from the concern to maintain the
referential and transactional integrity of the unit of work. But as the
footnote in page 93 (Section 3.5) mentions, the idea is to make this area of
the spec more standardized in future. 
   As the spec moves forward, we expect that new entity creation in @Pre-
callbacks are likely to be supported. Changing existing relations may not. 
   You are welcome to contribute your views to the JSR-318 mailing group.
  
  b) Access to entity manager is quite likely to be standardized in future
version of the spec. In expert group for version 2.1, we have seen several
requests on this aspect.

  So the broad approach for audit/change tracking via callback listeners,
that we have been discussing in this thread, is aligned with the evolution
of JPA specification. You are not taking a non-kosher approach. 

 

-
Pinaki Poddar
Chair, Apache OpenJPA Project
--
View this message in context: 
http://openjpa.208410.n2.nabble.com/Audit-log-with-OpenJPA-tp6557932p6583813.html
Sent from the OpenJPA Users mailing list archive at Nabble.com.


Re: Audit log with OpenJPA

2011-07-14 Thread Bengt Rodehav
Pinaki,

Thanks for your very insightful post. It feels like this is the way to go
then. I'll stick with this approach for now and try to follow the
development of JPA and OpenJPA.

Thanks for your help,

/Bengt

2011/7/14 Pinaki Poddar ppod...@apache.org

 Jim,
  I was making generic statements about audit and was not meant to address
 the specific approach you might have taken to suit your needs. I will take
 a
 closer look at the approach you have come up with.

  About 'delta computation', however, I find OpenJPA provides strong feature
 via its SavePointManager and restore facility. The advantage is that leaves
 the callback listeners stateless. Also, the managed entity knows which
 fields have been modified/dirtied -- which is essential to any delta
 computation.

 Bengt,
   Good to know you have made it working.

 Now the question/concern about spec-compliance what is permissible in
 @PreUpdate

  a) JPA spec so far have discouraged entity modification in callbacks.
 Specifically,
 JPA 2.0 spec does not allow access to EntityManager and modification of
 existing relations. These restrictions stem from the concern to maintain
 the
 referential and transactional integrity of the unit of work. But as the
 footnote in page 93 (Section 3.5) mentions, the idea is to make this area
 of
 the spec more standardized in future.
   As the spec moves forward, we expect that new entity creation in @Pre-
 callbacks are likely to be supported. Changing existing relations may not.
   You are welcome to contribute your views to the JSR-318 mailing group.

  b) Access to entity manager is quite likely to be standardized in future
 version of the spec. In expert group for version 2.1, we have seen several
 requests on this aspect.

  So the broad approach for audit/change tracking via callback listeners,
 that we have been discussing in this thread, is aligned with the evolution
 of JPA specification. You are not taking a non-kosher approach.



 -
 Pinaki Poddar
 Chair, Apache OpenJPA Project
 --
 View this message in context:
 http://openjpa.208410.n2.nabble.com/Audit-log-with-OpenJPA-tp6557932p6583813.html
 Sent from the OpenJPA Users mailing list archive at Nabble.com.



Re: Audit log with OpenJPA

2011-07-14 Thread Bengt Rodehav
Sorry Pinaki - not done with me yet

My intention was to audit log the whole object (serialized though) but the
method:

*SaveFieldManager.getState()*


returns an object where only the changed fields are initialized (seems like
it anyway). Is there a way I can get hold of the whole object (the previous
version of the object that is)?

/Bengt

2011/7/14 Bengt Rodehav be...@rodehav.com

 Pinaki,

 Thanks for your very insightful post. It feels like this is the way to go
 then. I'll stick with this approach for now and try to follow the
 development of JPA and OpenJPA.

 Thanks for your help,

 /Bengt


 2011/7/14 Pinaki Poddar ppod...@apache.org

 Jim,
  I was making generic statements about audit and was not meant to address
 the specific approach you might have taken to suit your needs. I will take
 a
 closer look at the approach you have come up with.

  About 'delta computation', however, I find OpenJPA provides strong
 feature
 via its SavePointManager and restore facility. The advantage is that
 leaves
 the callback listeners stateless. Also, the managed entity knows which
 fields have been modified/dirtied -- which is essential to any delta
 computation.

 Bengt,
   Good to know you have made it working.

 Now the question/concern about spec-compliance what is permissible in
 @PreUpdate

  a) JPA spec so far have discouraged entity modification in callbacks.
 Specifically,
 JPA 2.0 spec does not allow access to EntityManager and modification of
 existing relations. These restrictions stem from the concern to maintain
 the
 referential and transactional integrity of the unit of work. But as the
 footnote in page 93 (Section 3.5) mentions, the idea is to make this area
 of
 the spec more standardized in future.
   As the spec moves forward, we expect that new entity creation in @Pre-
 callbacks are likely to be supported. Changing existing relations may not.
   You are welcome to contribute your views to the JSR-318 mailing group.

  b) Access to entity manager is quite likely to be standardized in future
 version of the spec. In expert group for version 2.1, we have seen several
 requests on this aspect.

  So the broad approach for audit/change tracking via callback listeners,
 that we have been discussing in this thread, is aligned with the evolution
 of JPA specification. You are not taking a non-kosher approach.



 -
 Pinaki Poddar
 Chair, Apache OpenJPA Project
 --
 View this message in context:
 http://openjpa.208410.n2.nabble.com/Audit-log-with-OpenJPA-tp6557932p6583813.html
 Sent from the OpenJPA Users mailing list archive at Nabble.com.





Re: Audit log with OpenJPA

2011-07-13 Thread Pinaki Poddar
Hi,


 On PreUpdate I save an audit log entry describing the current entity.
 However, I guess I should
 audit log the object in its previous state not its current state -
 otherwise I need to audit log in the PreCreate as well - right? I think
 I'll have to use your solution, Pinaki, to get the previous state of the
 object since
 that's what I have to log in the PreUpdate. 
 

Yes. Any audit facility needs to have a snapshot of the entity when it
entered a persistence context, so at @PreUpdate or at any other time points,
it can figure out what has essentially been changed about that entity in a
transaction. Now either one can build their own mechanics to store the
original state of the entity or can use OpenJPA's own facility to access the
original state. The blog article showed the later approach.

Secondly, in my view, an audit facility should be orthogonal. The actual
domain entity need not know that it is being audited. Thereby, the domain
entity need not have an association or knowledge of an Audit object.   

Thirdly, the audit facility should allow the audit information be stored in
a separate database, in the same database or may even be logged in a file.
That is to say that persistence of audit information should be decoupled
from persistence of the domain objects. 

If you intend to store audit information as a persistent entity in the same
database as the domain entity, then the simple solution is something like
this in a domain class:

  @PreUpdate
  public void audit() {
  Audit audit = new Audit();
  // now populate audit information
  //  some serious delta computation

  // Now get the entity manager that is managing this current domain
object
  OpenJPAEntityManager em = 
OpenJPAPersistence.getEntityManager(this);

  // And persist the audit information in the same transaction
  em.persist(audit);
  }





-
Pinaki Poddar
Chair, Apache OpenJPA Project
--
View this message in context: 
http://openjpa.208410.n2.nabble.com/Audit-log-with-OpenJPA-tp6557932p6580549.html
Sent from the OpenJPA Users mailing list archive at Nabble.com.


Re: Audit log with OpenJPA

2011-07-13 Thread Bengt Rodehav
Pinaki,

I agree with all your statements. I would like to  keep the audit logging
out of my business domain (separating of concerns). I just hadn't found a
good way of doing this with JPA yet. Jim's approach gave me a way of being
able to create new entities in @PreUpdate however with the drawbacks I
mentioned (where one is that the domain model is affected).

Your solution avoided the relationship but didn't give a way to store the
audit log in a separate table. I fully agree that the persistence of the
audit logging should be independent of the domain objects and could even be
in log files.

I have been thinking of the approach you suggest but I didn't think it was
supported. I'm sure it's not supported by JPA since it seems you're not
allowed to create new entities in a @PreUpdate. Is it supported by OpenJPA?
Will it stay supported?

Thanks for your advice - I appreciate it,

/Bengt

2011/7/13 Pinaki Poddar ppod...@apache.org

 Hi,


  On PreUpdate I save an audit log entry describing the current entity.
  However, I guess I should
  audit log the object in its previous state not its current state -
  otherwise I need to audit log in the PreCreate as well - right? I think
  I'll have to use your solution, Pinaki, to get the previous state of the
  object since
  that's what I have to log in the PreUpdate.
 

 Yes. Any audit facility needs to have a snapshot of the entity when it
 entered a persistence context, so at @PreUpdate or at any other time
 points,
 it can figure out what has essentially been changed about that entity in a
 transaction. Now either one can build their own mechanics to store the
 original state of the entity or can use OpenJPA's own facility to access
 the
 original state. The blog article showed the later approach.

 Secondly, in my view, an audit facility should be orthogonal. The actual
 domain entity need not know that it is being audited. Thereby, the domain
 entity need not have an association or knowledge of an Audit object.

 Thirdly, the audit facility should allow the audit information be stored in
 a separate database, in the same database or may even be logged in a file.
 That is to say that persistence of audit information should be decoupled
 from persistence of the domain objects.

 If you intend to store audit information as a persistent entity in the same
 database as the domain entity, then the simple solution is something like
 this in a domain class:

  @PreUpdate
  public void audit() {
  Audit audit = new Audit();
  // now populate audit information
  //  some serious delta computation

  // Now get the entity manager that is managing this current domain
 object
  OpenJPAEntityManager em =
 OpenJPAPersistence.getEntityManager(this);

  // And persist the audit information in the same transaction
  em.persist(audit);
   }





 -
 Pinaki Poddar
 Chair, Apache OpenJPA Project
 --
 View this message in context:
 http://openjpa.208410.n2.nabble.com/Audit-log-with-OpenJPA-tp6557932p6580549.html
 Sent from the OpenJPA Users mailing list archive at Nabble.com.



Re: Audit log with OpenJPA

2011-07-13 Thread Bengt Rodehav
Just tried your suggestion Pinaki - it works fine and I can keep the audit
logging completely separate from my domain model. I even get rid of the join
table.

Now if this were clearly supported by OpenJPA (and by JPA in the future) I
think we have a clear winner...

/Bengt

2011/7/14 Bengt Rodehav be...@rodehav.com

 Pinaki,

 I agree with all your statements. I would like to  keep the audit logging
 out of my business domain (separating of concerns). I just hadn't found a
 good way of doing this with JPA yet. Jim's approach gave me a way of being
 able to create new entities in @PreUpdate however with the drawbacks I
 mentioned (where one is that the domain model is affected).

 Your solution avoided the relationship but didn't give a way to store the
 audit log in a separate table. I fully agree that the persistence of the
 audit logging should be independent of the domain objects and could even be
 in log files.

 I have been thinking of the approach you suggest but I didn't think it was
 supported. I'm sure it's not supported by JPA since it seems you're not
 allowed to create new entities in a @PreUpdate. Is it supported by OpenJPA?
 Will it stay supported?

 Thanks for your advice - I appreciate it,

 /Bengt

 2011/7/13 Pinaki Poddar ppod...@apache.org

 Hi,


  On PreUpdate I save an audit log entry describing the current entity.
  However, I guess I should
  audit log the object in its previous state not its current state -
  otherwise I need to audit log in the PreCreate as well - right? I think
  I'll have to use your solution, Pinaki, to get the previous state of the
  object since
  that's what I have to log in the PreUpdate.
 

 Yes. Any audit facility needs to have a snapshot of the entity when it
 entered a persistence context, so at @PreUpdate or at any other time
 points,
 it can figure out what has essentially been changed about that entity in a
 transaction. Now either one can build their own mechanics to store the
 original state of the entity or can use OpenJPA's own facility to access
 the
 original state. The blog article showed the later approach.

 Secondly, in my view, an audit facility should be orthogonal. The actual
 domain entity need not know that it is being audited. Thereby, the domain
 entity need not have an association or knowledge of an Audit object.

 Thirdly, the audit facility should allow the audit information be stored
 in
 a separate database, in the same database or may even be logged in a file.
 That is to say that persistence of audit information should be decoupled
 from persistence of the domain objects.

 If you intend to store audit information as a persistent entity in the
 same
 database as the domain entity, then the simple solution is something like
 this in a domain class:

  @PreUpdate
  public void audit() {
  Audit audit = new Audit();
  // now populate audit information
  //  some serious delta computation

  // Now get the entity manager that is managing this current
 domain
 object
  OpenJPAEntityManager em =
 OpenJPAPersistence.getEntityManager(this);

  // And persist the audit information in the same transaction
  em.persist(audit);
   }





 -
 Pinaki Poddar
 Chair, Apache OpenJPA Project
 --
 View this message in context:
 http://openjpa.208410.n2.nabble.com/Audit-log-with-OpenJPA-tp6557932p6580549.html
 Sent from the OpenJPA Users mailing list archive at Nabble.com.





Re: Audit log with OpenJPA

2011-07-13 Thread Jim Talbut

On 13/07/2011 21:14, Pinaki Poddar wrote:

Yes. Any audit facility needs to have a snapshot of the entity when it
entered a persistence context, so at @PreUpdate or at any other time points,
it can figure out what has essentially been changed about that entity in a
transaction. Now either one can build their own mechanics to store the
original state of the entity or can use OpenJPA's own facility to access the
original state. The blog article showed the later approach.

I also went with using the OpenJPA stored version of the original object.
There are a few niggles to getting that data that one has to work with, 
but I still think it's considerably less effort than building your own 
mechanism.

Secondly, in my view, an audit facility should be orthogonal. The actual
domain entity need not know that it is being audited. Thereby, the domain
entity need not have an association or knowledge of an Audit object.

I'd agree with that for a general purpose audit facility.
In my case I don't even call it audit it's change tracking, and the 
change information is displayed alongside the entities in the most 
common cases.

Thirdly, the audit facility should allow the audit information be stored in
a separate database, in the same database or may even be logged in a file.
That is to say that persistence of audit information should be decoupled
from persistence of the domain objects.

Again, true for a general purpose audit facility.
If you want to be really secure the audit log should be sent directly to 
a printer :)



If you intend to store audit information as a persistent entity in the same
database as the domain entity, then the simple solution is something like
this in a domain class:

   @PreUpdate
   public void audit() {
  Audit audit = new Audit();
   // now populate audit information
   //  some serious delta computation

   // Now get the entity manager that is managing this current domain
object
   OpenJPAEntityManager em =
OpenJPAPersistence.getEntityManager(this);

   // And persist the audit information in the same transaction
  em.persist(audit);
   }


I wonder if that bends the rules any more than my approach?

Jim


Re: Audit log with OpenJPA

2011-07-12 Thread Jim Talbut

On 07/07/2011 12:05, Bengt Rodehav wrote:

I'm using OpenJPA for persistence and would like to audit log any changes
made to my entities. I serialize the objects to JSON (with Gson) and store
them in a separate table in the database. Since the audit log needs to have
the correct id's, the audit logging must take place after the entity has
been persisted.

I was hoping I could use the @PostPersist and @PostUpdate life cycle
callbacks for this.

A bit late to the party, but this is what I've got working:

Change the entity ID column so it's not allocated by the database, then 
it becomes valid from the time the entity is persisted, rather than the 
time it's flushed.
By using a table type sequence generator the disadvantages relative to a 
database generated ID are few (and IME are only seen if you are abusing 
the IDs :) )


I only carry out an audit in @PreUpdate, because all I track is changes 
and there aren't any changes for a new record - so actually the ID 
generation should be irrelevant.
But by working in PreUpdate I've found that I am able to work with the 
entity manager and create new entities for the audit.


The entity being audited has a OneToMany join to the audit entries, so I 
don't have to call persist on the audit log object, I just add it to the 
collection in the entity being audited.


Jim



Re: Audit log with OpenJPA

2011-07-12 Thread Bengt Rodehav
Thanks for your post Jim,

In the past (when we rolled our own O/R mapping) we also generated the id's
ourselves via sequences stored in a dedicated table. Come to think of it,
one of the reasons was exactly what you are talking about - one can
reference the id even before the object is persisted. This is of course a
big benefit when it comes to audit logging (and actually other types of
logging as well). I will definitely revisit that.

Your other design decision is also interesting. By having a relationship to
the audit log entries JPA will persist the audit log entry for you - very
convenient indeed. A little similar to the way Pinaki described previously.
However you store the audit log in a separate table while Pinaki stores the
audit log together with the entity (in a separate column) that is being
persisted. I kind of like your approach better. I think an audit log can be
viewed from two different angles: the entity view and the user view. You
need to be able to see what changes have been made to an entity and possibly
even implment undo (like Pinaki). However, you also need to be able to track
all changes done by a specific user during a specific time period. The
latter is much easier with a centralized place for all audit log entries.
Can't really see how that can easily be done with Pinaki's approach.

The only thing I might miss from your solution then is the ability to
configure whether audit logging is enabled for an entity or not. Our
customers have different requirements here. But then again, this should be
possible in your approach as well. In the @PreUpdate method I could check
(somehow) if audit logging is enabled for this entity. If yes, then create
the audit log entry and add it to the collection. If not, then don't create
the audit log entry and nothing will be logged - right?

Have you had the need to configure OpenJPA in some specific way for
performance reasons? I guess you really want to avoid OpenJPA fetching all
your audit log entries every time an entity is fetched...

Also, I need to know whether this is a supported JPA/OpenJPA way of doing
things. My guess is yes since you don't actually use the entity manager
yourself.

Very interesting approach.

Thanks,

/Bengt



2011/7/12 Jim Talbut jtal...@spudsoft.co.uk

 On 07/07/2011 12:05, Bengt Rodehav wrote:

 I'm using OpenJPA for persistence and would like to audit log any changes
 made to my entities. I serialize the objects to JSON (with Gson) and store
 them in a separate table in the database. Since the audit log needs to
 have
 the correct id's, the audit logging must take place after the entity has
 been persisted.

 I was hoping I could use the @PostPersist and @PostUpdate life cycle
 callbacks for this.

 A bit late to the party, but this is what I've got working:

 Change the entity ID column so it's not allocated by the database, then it
 becomes valid from the time the entity is persisted, rather than the time
 it's flushed.
 By using a table type sequence generator the disadvantages relative to a
 database generated ID are few (and IME are only seen if you are abusing the
 IDs :) )

 I only carry out an audit in @PreUpdate, because all I track is changes and
 there aren't any changes for a new record - so actually the ID generation
 should be irrelevant.
 But by working in PreUpdate I've found that I am able to work with the
 entity manager and create new entities for the audit.

 The entity being audited has a OneToMany join to the audit entries, so I
 don't have to call persist on the audit log object, I just add it to the
 collection in the entity being audited.

 Jim




Re: Audit log with OpenJPA

2011-07-12 Thread Bengt Rodehav
Jim,

Why do you think that your approach is not supported by JPA? From other
posts on this list I've seen that you are allowed to add/enrich your entity
in the PreUpdate/PreCreate callbacks. That's all you are doing right. Then
JPA persists your enriched entities.

What do you violate?

/Bengt

2011/7/12 Jim Talbut jtal...@spudsoft.co.uk

 On 12/07/2011 08:49, Bengt Rodehav wrote:

 Your other design decision is also interesting. By having a relationship
 to
 the audit log entries JPA will persist the audit log entry for you - very
 convenient indeed. A little similar to the way Pinaki described
 previously.
 However you store the audit log in a separate table while Pinaki stores
 the
 audit log together with the entity (in a separate column) that is being
 persisted. I kind of like your approach better. I think an audit log can
 be
 viewed from two different angles: the entity view and the user view. You
 need to be able to see what changes have been made to an entity and
 possibly
 even implment undo (like Pinaki). However, you also need to be able to
 track
 all changes done by a specific user during a specific time period. The
 latter is much easier with a centralized place for all audit log entries.
 Can't really see how that can easily be done with Pinaki's approach.

 With the specifics of my implementation undo would be very awkward to
 implement, but that's because I'm trying to produce a textual change
 tracking log rather than an undo per-se.
 I could modify my layout to support undo, but it would still be more
 complex than a model that put the undo records in the original table.

  The only thing I might miss from your solution then is the ability to
 configure whether audit logging is enabled for an entity or not. Our
 customers have different requirements here. But then again, this should be
 possible in your approach as well. In the @PreUpdate method I could check
 (somehow) if audit logging is enabled for this entity. If yes, then create
 the audit log entry and add it to the collection. If not, then don't
 create
 the audit log entry and nothing will be logged - right?

 That's right.
 For my purposes I don't want to exclude any entities of a given type - so
 three different (unrelated) entity classes perform auditing but there is no
 filtering of entities of an audited type.

  Have you had the need to configure OpenJPA in some specific way for
 performance reasons? I guess you really want to avoid OpenJPA fetching all
 your audit log entries every time an entity is fetched...

 All I've done is make the audit entries lazy-fetch and I believe that works
 (though honestly I haven't actually tested it).

  Also, I need to know whether this is a supported JPA/OpenJPA way of doing
 things. My guess is yes since you don't actually use the entity manager
 yourself.

 It's not, that's the big downside.
 The only way you're going to get an official approach is with a JDBC call
 in the same transaction (which I ditched because of the difficulties of
 getting hold of the transactional context and other things from within the
 listener).
 If I find that the approach fails in a future version of OpenJPA I'll
 switch to JDBC, by having the entities in a separate table this is quite a
 clean swap and the only difficulty is getting the necessary context
 available at the right place.

 Jim



Re: Audit log with OpenJPA

2011-07-12 Thread Jim Talbut

On 12/07/2011 09:33, Bengt Rodehav wrote:

Why do you think that your approach is not supported by JPA? From other
posts on this list I've seen that you are allowed to add/enrich your entity
in the PreUpdate/PreCreate callbacks. That's all you are doing right. Then
JPA persists your enriched entities.


I asked on this list a few months ago:
http://web.archiveorange.com/archive/v/tXrrxw9bXkttUykS7B6K

You can change the state of entities, but creating new entities is not 
permitted by the JPA spec.
At the moment it does work, and I now what I'm going to do if it stops 
working, so I'm happy.
I'd be happier if OpenJPA explicitly supported it, but it doesn't keep 
me awake at night.


Jim


Re: Audit log with OpenJPA

2011-07-12 Thread Bengt Rodehav
Jim,

I tried your approach (I think) but got the following exception:

*openjpa-2.0.1-r422266:989424 nonfatal user error
 org.apache.openjpa.persistence.InvalidStateException: Encountered unmanaged
 object in persistent field
 se.digia.maia.common.persistence.EntityBase.auditLogelement:class
 se.digia.maia.common.auditlog.domain.AuditLog during flush.  However, this
 field does not allow cascade persist. Set the cascade attribute for this
 field to CascadeType.PERSIST or CascadeType.ALL (JPA annotations) or
 persist or all (JPA orm.xml), or enable cascade-persist globally, or
 manually persist the related field value prior to flushing. You cannot flush
 unmanaged objects or graphs that have persistent associations to unmanaged
 objects.
 **FailedObject: se.digia.maia.common.auditlog.domain.AuditLog@39bc82
 ** at
 org.apache.openjpa.kernel.SingleFieldManager.preFlushPC(SingleFieldManager.java:767)
 ** at
 org.apache.openjpa.kernel.SingleFieldManager.preFlushPCs(SingleFieldManager.java:748)
 ** at
 org.apache.openjpa.kernel.SingleFieldManager.preFlush(SingleFieldManager.java:642)
 ** at
 org.apache.openjpa.kernel.SingleFieldManager.preFlush(SingleFieldManager.java:575)
 ** at
 org.apache.openjpa.kernel.SingleFieldManager.preFlush(SingleFieldManager.java:491)
 ** at
 org.apache.openjpa.kernel.StateManagerImpl.preFlush(StateManagerImpl.java:2957)
 ** at
 org.apache.openjpa.kernel.PDirtyState.beforeFlush(PDirtyState.java:38)
 ** at
 org.apache.openjpa.kernel.StateManagerImpl.beforeFlush(StateManagerImpl.java:1047)
 ** at org.apache.openjpa.kernel.BrokerImpl.flush(BrokerImpl.java:2077)
 ** at org.apache.openjpa.kernel.BrokerImpl.flushSafe(BrokerImpl.java:2037)
 ** at
 org.apache.openjpa.kernel.BrokerImpl.beforeCompletion(BrokerImpl.java:1955)
 ** at
 org.apache.openjpa.kernel.LocalManagedRuntime.commit(LocalManagedRuntime.java:81)
 ** at org.apache.openjpa.kernel.BrokerImpl.commit(BrokerImpl.java:1479)
 ** at
 org.apache.openjpa.kernel.DelegatingBroker.commit(DelegatingBroker.java:925)
 ** at
 org.apache.openjpa.persistence.EntityManagerImpl.commit(EntityManagerImpl.java:560)
 ** at
 se.digia.maia.core.bu.test.CRUDTest.updateBusinessUnitTest(CRUDTest.java:141)
 *


I use OpenJPA 2.0.1. This is my relationship to the audit log table:

  @OneToMany
  @JoinTable(
name = ENTITY_ALOG,
joinColumns = @JoinColumn(name = ENTITY_ID),
inverseJoinColumns = @JoinColumn(name = ALOG_ID))
  private CollectionAuditLog auditLog;

This is my @PreUpdate method:

  @PreUpdate
  public void beforeUpdate() {
setUpdatedWhen(Calendar.getInstance());
setUpdatedBy(Session.getCurrentUser());
if (this.getClass().getAnnotation(Audit.class) != null) {
  AuditLog al = new AuditLog();
  al.setLogEntry(serialization of object);
  auditLog.add(al);
}
  }

OpenJPA doesn't seem to like this. What did you do differently?

/Bengt

2011/7/12 Bengt Rodehav be...@rodehav.com

 OK - I didn't know that.

 I agree that it would be nice if the OpenJPA guys would support this
 behaviour. My experience of standards (like JPA) is that the standard itself
 is rarely enough for production purposes. Things outside of the standard
 need to be in place as well. Then, after a while, the standard will
 sometimes adapt to reality and incorporate what has become the de facto
 standard.

 In this case, it is clear that the behaviour of the life-cycle callback
 methods is not defined enough in the standard. The implementations should
 therefore create a de facto standard. Let's hope they do...

 /Bengt

 2011/7/12 Jim Talbut jtal...@spudsoft.co.uk

 On 12/07/2011 09:33, Bengt Rodehav wrote:

 Why do you think that your approach is not supported by JPA? From other
 posts on this list I've seen that you are allowed to add/enrich your
 entity
 in the PreUpdate/PreCreate callbacks. That's all you are doing right.
 Then
 JPA persists your enriched entities.


 I asked on this list a few months ago:
 http://web.archiveorange.com/**archive/v/tXrrxw9bXkttUykS7B6Khttp://web.archiveorange.com/archive/v/tXrrxw9bXkttUykS7B6K

 You can change the state of entities, but creating new entities is not
 permitted by the JPA spec.
 At the moment it does work, and I now what I'm going to do if it stops
 working, so I'm happy.
 I'd be happier if OpenJPA explicitly supported it, but it doesn't keep me
 awake at night.

 Jim





Re: Audit log with OpenJPA

2011-07-08 Thread Bengt Rodehav
Indeed very interesting stuff (JEST). I'm not sure whether I want straight
lines from the client to the persistence layer though. Normally you would
want a layer in between for adding business logic, security etc. What is
interesting is to send general queries from the client to the server and
also the handling of whole object graphs both to and from the server. I
would like to be able to use those facilities in my internal implementation
of my server side services. I would, however, hesitate to use it as my
server side services straight off.

/Bengt

2011/7/8 Pinaki Poddar ppod...@apache.org

  However, I store the JSON in a database and I was hoping to use JPA for
 this

 Actually, storing JSON in relational database would not permit query based
 on property values. But OpenJPA can provide JSON formatted-data for any web
 UI.

 To more about t, following references can help

 [1] http://www.ibm.com/developerworks/java/library/j-jest/?ca=drs-
 [2] http://openjpa.apache.org/jest
 [3]

 https://www.ibm.com/developerworks/mydeveloperworks/blogs/pinaki/tags/jest?lang=en

 -
 Pinaki
 --
 View this message in context:
 http://openjpa.208410.n2.nabble.com/Audit-log-with-OpenJPA-tp6557932p6560732.html
 Sent from the OpenJPA Users mailing list archive at Nabble.com.



Re: Audit log with OpenJPA

2011-07-08 Thread Bengt Rodehav
Pinaki,

Can you point me to where I can find documentation about acessing the entity
manager from the life cycle callbacks? Will it be supported in OpenJPA in
the future? Can I rely on it?

/Bengt

2011/7/8 Pinaki Poddar ppod...@apache.org

  you actually store it in the object itself.
 That's right. This allows in-memory rollback.

 Given that the entire 'clean' or 'original' state is available in the
 technique I described, the application can make several decisions on
 a) what should be logged in an audit trail -- the entire object in a
 separate database/schema, a serialized blob or a JSON stream or whatever.
 b) because the technique is based on OpenJPA internal, if an application
 decides to take the 'blue pill', then it can simply ask the managed object
 which fields have been 'dirtied' if it requires to compute delta
 efficiently.

 Another related but separate point:
 I have noticed lot of requests/annoyance from the users on the limitation
 of
 callback listener methods having no access to the persistence context.
 Again, in OpenJPA runtime, the managed entity does know its persistence
 context. If the application is ready for a OpenJPA-specific  cast, then the
 handle to the persistence context is right there in the entity.

 -
 Pinaki
 --
 View this message in context:
 http://openjpa.208410.n2.nabble.com/Audit-log-with-OpenJPA-tp6557932p6560548.html
 Sent from the OpenJPA Users mailing list archive at Nabble.com.



Re: Audit log with OpenJPA

2011-07-07 Thread Jari Fredriksson
7.7.2011 14:05, Bengt Rodehav kirjoitti:
 I'm using OpenJPA for persistence and would like to audit log any changes
 made to my entities. I serialize the objects to JSON (with Gson) and store
 them in a separate table in the database. Since the audit log needs to have
 the correct id's, the audit logging must take place after the entity has
 been persisted.
 
 I was hoping I could use the @PostPersist and @PostUpdate life cycle
 callbacks for this. I do seem to have the right information available and
 the serialization works fine but I don't know how I can persist my audit log
 entries at this point. From what I've read, I'm not allowed to use the
 entity manager in a Post lifecycle callback which of course makes this
 hard.
 
 What do you recommend? Is there a good place in JPA/OpenJPA where I
 automatically can trigger the storing of an audit log entry as described
 above. Of course I can move this logic up from the persistence layer to a
 place where I can first have the entity manager persist my entity and then
 explicitly call another service to do the audit log. However, this is a
 pretty general mechanism that I would like to have automatic support for in
 my framework which is why I would like to have it pushed down into the
 persistence layer.
 
 Any ideas?
 

I have not done anything like this, but some kind of queue and a
separate processor for that queue might be a solution.

Maybe some message queue? Or a singleton Hashtable containing entries,
and a separate thread for persisting these to database.

Something like that.



-- 

AWAKE! FEAR! FIRE! FOES! AWAKE!
FEAR! FIRE! FOES!
AWAKE! AWAKE!
-- J. R. R. Tolkien



signature.asc
Description: OpenPGP digital signature


Re: Audit log with OpenJPA

2011-07-07 Thread David Goodenough
On Thursday 07 Jul 2011, Bengt Rodehav wrote:
 I'm using OpenJPA for persistence and would like to audit log any changes
 made to my entities. I serialize the objects to JSON (with Gson) and store
 them in a separate table in the database. Since the audit log needs to have
 the correct id's, the audit logging must take place after the entity has
 been persisted.
 
 I was hoping I could use the @PostPersist and @PostUpdate life cycle
 callbacks for this. I do seem to have the right information available and
 the serialization works fine but I don't know how I can persist my audit
 log entries at this point. From what I've read, I'm not allowed to use the
 entity manager in a Post lifecycle callback which of course makes this
 hard.
 
 What do you recommend? Is there a good place in JPA/OpenJPA where I
 automatically can trigger the storing of an audit log entry as described
 above. Of course I can move this logic up from the persistence layer to a
 place where I can first have the entity manager persist my entity and then
 explicitly call another service to do the audit log. However, this is a
 pretty general mechanism that I would like to have automatic support for in
 my framework which is why I would like to have it pushed down into the
 persistence layer.
 
 Any ideas?
 
 /Bengt
You could of course cheat.

While you can not access the entiry manager, there is nothing to stop you
using JDBC.  It would probably not be a good idea to access a table that
JPA is using, but if this audit trail is write only for this app and only
read elsewhere that would solve the problem.

David


Re: Audit log with OpenJPA

2011-07-07 Thread Andrew Thompson
You might take a look at how hades
(http://hades.synyx.org/static/2.x/site/org.synyx.hades/reference/html/auditing.html)
 does something close to what you're describing.  Or http://www.jboss.org/envers

-Andy

On Thu, 2011-07-07 at 15:35 +0100, David Goodenough wrote: 
 On Thursday 07 Jul 2011, Bengt Rodehav wrote:
  I'm using OpenJPA for persistence and would like to audit log any changes
  made to my entities. I serialize the objects to JSON (with Gson) and store
  them in a separate table in the database. Since the audit log needs to have
  the correct id's, the audit logging must take place after the entity has
  been persisted.
  
  I was hoping I could use the @PostPersist and @PostUpdate life cycle
  callbacks for this. I do seem to have the right information available and
  the serialization works fine but I don't know how I can persist my audit
  log entries at this point. From what I've read, I'm not allowed to use the
  entity manager in a Post lifecycle callback which of course makes this
  hard.
  
  What do you recommend? Is there a good place in JPA/OpenJPA where I
  automatically can trigger the storing of an audit log entry as described
  above. Of course I can move this logic up from the persistence layer to a
  place where I can first have the entity manager persist my entity and then
  explicitly call another service to do the audit log. However, this is a
  pretty general mechanism that I would like to have automatic support for in
  my framework which is why I would like to have it pushed down into the
  persistence layer.
  
  Any ideas?
  
  /Bengt
 You could of course cheat.
 
 While you can not access the entiry manager, there is nothing to stop you
 using JDBC.  It would probably not be a good idea to access a table that
 JPA is using, but if this audit trail is write only for this app and only
 read elsewhere that would solve the problem.
 
 David



Re: Audit log with OpenJPA

2011-07-07 Thread Bengt Rodehav
Jari,

Yes an asynchronous queue is definitely an option. I've actually used that
approach before. It makes a lot of sense when trying to achieve high
throughput since the audit logging can then be done on lower priority.

I was however hoping to be able to use JPA for this since a queue increases
the complexity significantly (also regarding testing).

Thanks,

/Bengt

2011/7/7 Jari Fredriksson ja...@iki.fi

 7.7.2011 14:05, Bengt Rodehav kirjoitti:
  I'm using OpenJPA for persistence and would like to audit log any changes
  made to my entities. I serialize the objects to JSON (with Gson) and
 store
  them in a separate table in the database. Since the audit log needs to
 have
  the correct id's, the audit logging must take place after the entity has
  been persisted.
 
  I was hoping I could use the @PostPersist and @PostUpdate life cycle
  callbacks for this. I do seem to have the right information available and
  the serialization works fine but I don't know how I can persist my audit
 log
  entries at this point. From what I've read, I'm not allowed to use the
  entity manager in a Post lifecycle callback which of course makes this
  hard.
 
  What do you recommend? Is there a good place in JPA/OpenJPA where I
  automatically can trigger the storing of an audit log entry as described
  above. Of course I can move this logic up from the persistence layer to a
  place where I can first have the entity manager persist my entity and
 then
  explicitly call another service to do the audit log. However, this is a
  pretty general mechanism that I would like to have automatic support for
 in
  my framework which is why I would like to have it pushed down into the
  persistence layer.
 
  Any ideas?
 

 I have not done anything like this, but some kind of queue and a
 separate processor for that queue might be a solution.

 Maybe some message queue? Or a singleton Hashtable containing entries,
 and a separate thread for persisting these to database.

 Something like that.



 --

 AWAKE! FEAR! FIRE! FOES! AWAKE!
FEAR! FIRE! FOES!
AWAKE! AWAKE!
-- J. R. R. Tolkien




Re: Audit log with OpenJPA

2011-07-07 Thread Bengt Rodehav
Thanks for your reply David,

I wouldn't rule out cheating although I'd rather not. I have no experience
in mixing JDBC and JPA. What would happen transaction wise? Can they both be
part of the same transaction?

/Bengt

2011/7/7 David Goodenough david.goodeno...@btconnect.com

 On Thursday 07 Jul 2011, Bengt Rodehav wrote:
  I'm using OpenJPA for persistence and would like to audit log any changes
  made to my entities. I serialize the objects to JSON (with Gson) and
 store
  them in a separate table in the database. Since the audit log needs to
 have
  the correct id's, the audit logging must take place after the entity has
  been persisted.
 
  I was hoping I could use the @PostPersist and @PostUpdate life cycle
  callbacks for this. I do seem to have the right information available and
  the serialization works fine but I don't know how I can persist my audit
  log entries at this point. From what I've read, I'm not allowed to use
 the
  entity manager in a Post lifecycle callback which of course makes this
  hard.
 
  What do you recommend? Is there a good place in JPA/OpenJPA where I
  automatically can trigger the storing of an audit log entry as described
  above. Of course I can move this logic up from the persistence layer to a
  place where I can first have the entity manager persist my entity and
 then
  explicitly call another service to do the audit log. However, this is a
  pretty general mechanism that I would like to have automatic support for
 in
  my framework which is why I would like to have it pushed down into the
  persistence layer.
 
  Any ideas?
 
  /Bengt
 You could of course cheat.

 While you can not access the entiry manager, there is nothing to stop you
 using JDBC.  It would probably not be a good idea to access a table that
 JPA is using, but if this audit trail is write only for this app and only
 read elsewhere that would solve the problem.

 David



Re: Audit log with OpenJPA

2011-07-07 Thread Rick Curtis
Perhaps you could use a separate PU for your audit logging? That should be
safe to use inside of a lifecycle callback.

On Thu, Jul 7, 2011 at 11:36 AM, Bengt Rodehav be...@rodehav.com wrote:

 Jari,

 Yes an asynchronous queue is definitely an option. I've actually used that
 approach before. It makes a lot of sense when trying to achieve high
 throughput since the audit logging can then be done on lower priority.

 I was however hoping to be able to use JPA for this since a queue increases
 the complexity significantly (also regarding testing).

 Thanks,

 /Bengt

 2011/7/7 Jari Fredriksson ja...@iki.fi

  7.7.2011 14:05, Bengt Rodehav kirjoitti:
   I'm using OpenJPA for persistence and would like to audit log any
 changes
   made to my entities. I serialize the objects to JSON (with Gson) and
  store
   them in a separate table in the database. Since the audit log needs to
  have
   the correct id's, the audit logging must take place after the entity
 has
   been persisted.
  
   I was hoping I could use the @PostPersist and @PostUpdate life cycle
   callbacks for this. I do seem to have the right information available
 and
   the serialization works fine but I don't know how I can persist my
 audit
  log
   entries at this point. From what I've read, I'm not allowed to use the
   entity manager in a Post lifecycle callback which of course makes
 this
   hard.
  
   What do you recommend? Is there a good place in JPA/OpenJPA where I
   automatically can trigger the storing of an audit log entry as
 described
   above. Of course I can move this logic up from the persistence layer to
 a
   place where I can first have the entity manager persist my entity and
  then
   explicitly call another service to do the audit log. However, this is a
   pretty general mechanism that I would like to have automatic support
 for
  in
   my framework which is why I would like to have it pushed down into the
   persistence layer.
  
   Any ideas?
  
 
  I have not done anything like this, but some kind of queue and a
  separate processor for that queue might be a solution.
 
  Maybe some message queue? Or a singleton Hashtable containing entries,
  and a separate thread for persisting these to database.
 
  Something like that.
 
 
 
  --
 
  AWAKE! FEAR! FIRE! FOES! AWAKE!
 FEAR! FIRE! FOES!
 AWAKE! AWAKE!
 -- J. R. R. Tolkien
 
 




-- 
*Rick Curtis*


Re: Audit log with OpenJPA

2011-07-07 Thread Bengt Rodehav
I actually use the same approach as Hades for createdBy, updatedBy,
createdWhen and updatedWhen. In addition to this basic audit logging I also
want to log all historical versions together with information about who
updated the object.

I've read a little bit about Envers. I didn't want to bring it up since this
is an OpenJPA mailing list. It does look interesting but I think it requires
Hibernate which I do not intend to go back to. (I'm actually moving away
from Hibernate). Also, I'm a bit hesitant to store copies of my rows in
special audit tables since it also means database migration of those tables.
I think serializing the audit log entries and putting them in one column is
a better approach from a maintenance perspective.

But it would be nice if OpenJPA would provide a callback or some mechanism
(even if it's not standard JPA) that would allow further updates/inserts in
a callback.

Are there any such plans?

/Bengt

2011/7/7 Andrew Thompson at2...@columbia.edu

 You might take a look at how hades
 (
 http://hades.synyx.org/static/2.x/site/org.synyx.hades/reference/html/auditing.html)
 does something close to what you're describing.  Or
 http://www.jboss.org/envers

 -Andy

 On Thu, 2011-07-07 at 15:35 +0100, David Goodenough wrote:
  On Thursday 07 Jul 2011, Bengt Rodehav wrote:
   I'm using OpenJPA for persistence and would like to audit log any
 changes
   made to my entities. I serialize the objects to JSON (with Gson) and
 store
   them in a separate table in the database. Since the audit log needs to
 have
   the correct id's, the audit logging must take place after the entity
 has
   been persisted.
  
   I was hoping I could use the @PostPersist and @PostUpdate life cycle
   callbacks for this. I do seem to have the right information available
 and
   the serialization works fine but I don't know how I can persist my
 audit
   log entries at this point. From what I've read, I'm not allowed to use
 the
   entity manager in a Post lifecycle callback which of course makes
 this
   hard.
  
   What do you recommend? Is there a good place in JPA/OpenJPA where I
   automatically can trigger the storing of an audit log entry as
 described
   above. Of course I can move this logic up from the persistence layer to
 a
   place where I can first have the entity manager persist my entity and
 then
   explicitly call another service to do the audit log. However, this is a
   pretty general mechanism that I would like to have automatic support
 for in
   my framework which is why I would like to have it pushed down into the
   persistence layer.
  
   Any ideas?
  
   /Bengt
  You could of course cheat.
 
  While you can not access the entiry manager, there is nothing to stop you
  using JDBC.  It would probably not be a good idea to access a table that
  JPA is using, but if this audit trail is write only for this app and only
  read elsewhere that would solve the problem.
 
  David




Re: Audit log with OpenJPA

2011-07-07 Thread Bengt Rodehav
Interesting suggestion. Can I still share the same transaction between the
original update and my audit log insert?

/Bengt

2011/7/7 Rick Curtis curti...@gmail.com

 Perhaps you could use a separate PU for your audit logging? That should be
 safe to use inside of a lifecycle callback.

 On Thu, Jul 7, 2011 at 11:36 AM, Bengt Rodehav be...@rodehav.com wrote:

  Jari,
 
  Yes an asynchronous queue is definitely an option. I've actually used
 that
  approach before. It makes a lot of sense when trying to achieve high
  throughput since the audit logging can then be done on lower priority.
 
  I was however hoping to be able to use JPA for this since a queue
 increases
  the complexity significantly (also regarding testing).
 
  Thanks,
 
  /Bengt
 
  2011/7/7 Jari Fredriksson ja...@iki.fi
 
   7.7.2011 14:05, Bengt Rodehav kirjoitti:
I'm using OpenJPA for persistence and would like to audit log any
  changes
made to my entities. I serialize the objects to JSON (with Gson) and
   store
them in a separate table in the database. Since the audit log needs
 to
   have
the correct id's, the audit logging must take place after the entity
  has
been persisted.
   
I was hoping I could use the @PostPersist and @PostUpdate life cycle
callbacks for this. I do seem to have the right information available
  and
the serialization works fine but I don't know how I can persist my
  audit
   log
entries at this point. From what I've read, I'm not allowed to use
 the
entity manager in a Post lifecycle callback which of course makes
  this
hard.
   
What do you recommend? Is there a good place in JPA/OpenJPA where I
automatically can trigger the storing of an audit log entry as
  described
above. Of course I can move this logic up from the persistence layer
 to
  a
place where I can first have the entity manager persist my entity and
   then
explicitly call another service to do the audit log. However, this is
 a
pretty general mechanism that I would like to have automatic support
  for
   in
my framework which is why I would like to have it pushed down into
 the
persistence layer.
   
Any ideas?
   
  
   I have not done anything like this, but some kind of queue and a
   separate processor for that queue might be a solution.
  
   Maybe some message queue? Or a singleton Hashtable containing entries,
   and a separate thread for persisting these to database.
  
   Something like that.
  
  
  
   --
  
   AWAKE! FEAR! FIRE! FOES! AWAKE!
  FEAR! FIRE! FOES!
  AWAKE! AWAKE!
  -- J. R. R. Tolkien
  
  
 



 --
 *Rick Curtis*



Re: Audit log with OpenJPA

2011-07-07 Thread Jari Fredriksson

How is your JPA accessed? I have done JPA, and Audit logging on top of
it, but it was into XML files, and performed in a EJB3 Session Bean. The
JPA objects were plain simple, but they were all accessed via a Session
Bean Facade. I did it with XML because boss wanted so, but could have
been database as well.

7.7.2011 19:49, Bengt Rodehav kirjoitti:
 I actually use the same approach as Hades for createdBy, updatedBy,
 createdWhen and updatedWhen. In addition to this basic audit logging I also
 want to log all historical versions together with information about who
 updated the object.
 
 I've read a little bit about Envers. I didn't want to bring it up since this
 is an OpenJPA mailing list. It does look interesting but I think it requires
 Hibernate which I do not intend to go back to. (I'm actually moving away
 from Hibernate). Also, I'm a bit hesitant to store copies of my rows in
 special audit tables since it also means database migration of those tables.
 I think serializing the audit log entries and putting them in one column is
 a better approach from a maintenance perspective.
 
 But it would be nice if OpenJPA would provide a callback or some mechanism
 (even if it's not standard JPA) that would allow further updates/inserts in
 a callback.
 
 Are there any such plans?
 
 /Bengt
 
 2011/7/7 Andrew Thompson at2...@columbia.edu
 
 You might take a look at how hades
 (
 http://hades.synyx.org/static/2.x/site/org.synyx.hades/reference/html/auditing.html)
 does something close to what you're describing.  Or
 http://www.jboss.org/envers

 -Andy

 On Thu, 2011-07-07 at 15:35 +0100, David Goodenough wrote:
 On Thursday 07 Jul 2011, Bengt Rodehav wrote:
 I'm using OpenJPA for persistence and would like to audit log any
 changes
 made to my entities. I serialize the objects to JSON (with Gson) and
 store
 them in a separate table in the database. Since the audit log needs to
 have
 the correct id's, the audit logging must take place after the entity
 has
 been persisted.

 I was hoping I could use the @PostPersist and @PostUpdate life cycle
 callbacks for this. I do seem to have the right information available
 and
 the serialization works fine but I don't know how I can persist my
 audit
 log entries at this point. From what I've read, I'm not allowed to use
 the
 entity manager in a Post lifecycle callback which of course makes
 this
 hard.

 What do you recommend? Is there a good place in JPA/OpenJPA where I
 automatically can trigger the storing of an audit log entry as
 described
 above. Of course I can move this logic up from the persistence layer to
 a
 place where I can first have the entity manager persist my entity and
 then
 explicitly call another service to do the audit log. However, this is a
 pretty general mechanism that I would like to have automatic support
 for in
 my framework which is why I would like to have it pushed down into the
 persistence layer.

 Any ideas?

 /Bengt
 You could of course cheat.

 While you can not access the entiry manager, there is nothing to stop you
 using JDBC.  It would probably not be a good idea to access a table that
 JPA is using, but if this audit trail is write only for this app and only
 read elsewhere that would solve the problem.

 David


 


-- 

Q:  What's the difference betweeen USL and the Graf Zeppelin?
A:  The Graf Zeppelin represented cutting edge technology for its time.



signature.asc
Description: OpenPGP digital signature


Re: Audit log with OpenJPA

2011-07-07 Thread No1UNo
Bengt:

I'm enjoying this discussion because of the gymnastics that were required for 
my solutions.  There is no easy way that I am aware of -- but I would LOVE to 
be wrong.

Here's what I did (and, no, I'm not particularly proud of the solution):

(1) For the primary entities, add tracking data (timestamp, user, etc.) plus an 
entityID.
(2) On an update,
* clone the data in the entity and update the tracking data.  Copy the 
old entityID.
* mark the previous entity as out-of-date (to speed up searches)
* persist both entities
(3) On an insert,
* persist the new entity and increment the entityID
(4) Update the queries to extract only those records where the 'out-of-date' 
flag was not set.

This results in both current and historical entities being preserved in the 
same table.  This will reduce performance as the indices are larger than are 
necessary for daily operation.  This solution can be combined with a nightly 
script which moves out-of-date records from the main table to archived tables.

The entity copy is a real pain but seems to be necessary.  See the 'How to 
persist duplicate of an entity?' thread from January 2011.  As I wrote earlier:

 I would _love_ to have function that would 'reset' a detached entity.  
 Perhaps something like
 
   em.detach(myObj);  // ensure that the entity has been detached.
   OpenJPAEntityManager kem = OpenJPAPersistence.cast(em);
   kem.reset(myObj);
 
 with the result of the 'reset' operation being a class which is again virgin, 
 i.e.
 
   myObj.id == 0
   myObj.version = 0
   myObj.pcDetachedState == null
   myObj.pcStateManager == null
 
 and so forth for any children.


This would greatly simplify the cloning process.

-=- Jerry





On Jul 7, 2011, at 12:50 PM, Bengt Rodehav [via OpenJPA] wrote:

 I actually use the same approach as Hades for createdBy, updatedBy, 
 createdWhen and updatedWhen. In addition to this basic audit logging I also 
 want to log all historical versions together with information about who 
 updated the object. 
 
 I've read a little bit about Envers. I didn't want to bring it up since this 
 is an OpenJPA mailing list. It does look interesting but I think it requires 
 Hibernate which I do not intend to go back to. (I'm actually moving away 
 from Hibernate). Also, I'm a bit hesitant to store copies of my rows in 
 special audit tables since it also means database migration of those tables. 
 I think serializing the audit log entries and putting them in one column is 
 a better approach from a maintenance perspective. 
 
 But it would be nice if OpenJPA would provide a callback or some mechanism 
 (even if it's not standard JPA) that would allow further updates/inserts in 
 a callback. 
 
 Are there any such plans? 
 
 /Bengt 
 
 2011/7/7 Andrew Thompson [hidden email] 
 
  You might take a look at how hades 
  ( 
  http://hades.synyx.org/static/2.x/site/org.synyx.hades/reference/html/auditing.html)
   
  does something close to what you're describing.  Or 
  http://www.jboss.org/envers
  
  -Andy 
  
  On Thu, 2011-07-07 at 15:35 +0100, David Goodenough wrote: 
   On Thursday 07 Jul 2011, Bengt Rodehav wrote: 
I'm using OpenJPA for persistence and would like to audit log any 
  changes 
made to my entities. I serialize the objects to JSON (with Gson) and 
  store 
them in a separate table in the database. Since the audit log needs to 
  have 
the correct id's, the audit logging must take place after the entity 
  has 
been persisted. 

I was hoping I could use the @PostPersist and @PostUpdate life cycle 
callbacks for this. I do seem to have the right information available 
  and 
the serialization works fine but I don't know how I can persist my 
  audit 
log entries at this point. From what I've read, I'm not allowed to use 
  the 
entity manager in a Post lifecycle callback which of course makes 
  this 
hard. 

What do you recommend? Is there a good place in JPA/OpenJPA where I 
automatically can trigger the storing of an audit log entry as 
  described 
above. Of course I can move this logic up from the persistence layer to 
  a 
place where I can first have the entity manager persist my entity and 
  then 
explicitly call another service to do the audit log. However, this is a 
pretty general mechanism that I would like to have automatic support 
  for in 
my framework which is why I would like to have it pushed down into the 
persistence layer. 

Any ideas? 

/Bengt 
   You could of course cheat. 
   
   While you can not access the entiry manager, there is nothing to stop you 
   using JDBC.  It would probably not be a good idea to access a table that 
   JPA is using, but if this audit trail is write only for this app and only 
   read elsewhere that would solve the problem. 
   
   David 
  
  
 
 
 If you reply to this email, your message will be added to the 

Re: Audit log with OpenJPA

2011-07-07 Thread Pinaki Poddar
Hi,
  Good to see lot of new ideas about auditing.
  Here is one more [1] that uses OpenJPA specific internals of accessing the
original state of an entity.
The comparison of the current state and original state to decide upon the
audit message is provided trivially in this example -- but at the level at
which OpenJPA API is being accessed here, much more facilities are available
to compute the 'delta'. 
  
[1]   
http://webspherepersistence.blogspot.com/2009/01/auditing-with-openjpa.html

-
Pinaki 
--
View this message in context: 
http://openjpa.208410.n2.nabble.com/Audit-log-with-OpenJPA-tp6557932p6559730.html
Sent from the OpenJPA Users mailing list archive at Nabble.com.


Re: Audit log with OpenJPA

2011-07-07 Thread Mark Struberg
Hi Folks!

I also use auditing with OpenJPA:
http://struberg.wordpress.com/2010/07/31/howto-changelog-with-jpa/

but it currently only works with a patched OpenJPA 2.2.x version.
https://issues.apache.org/jira/browse/OPENJPA-1873

We fixed a few parts already, but the POST_LOAD_ON_MERGE isn't yet submitted 
since we didn't quite agree if it is spec conform.

LieGrue,
strub


--- On Thu, 7/7/11, Pinaki Poddar ppod...@apache.org wrote:

 From: Pinaki Poddar ppod...@apache.org
 Subject: Re: Audit log with OpenJPA
 To: users@openjpa.apache.org
 Date: Thursday, July 7, 2011, 7:58 PM
 Hi,
   Good to see lot of new ideas about auditing.
   Here is one more [1] that uses OpenJPA specific
 internals of accessing the
 original state of an entity.
 The comparison of the current state and original state to
 decide upon the
 audit message is provided trivially in this example -- but
 at the level at
 which OpenJPA API is being accessed here, much more
 facilities are available
 to compute the 'delta'. 
   
 [1]   
 http://webspherepersistence.blogspot.com/2009/01/auditing-with-openjpa.html
 
 -
 Pinaki 
 --
 View this message in context: 
 http://openjpa.208410.n2.nabble.com/Audit-log-with-OpenJPA-tp6557932p6559730.html
 Sent from the OpenJPA Users mailing list archive at
 Nabble.com.



Re: Audit log with OpenJPA

2011-07-07 Thread Bengt Rodehav
Jarl,

In production I run my application in OSGi (Apache Karaf). I use Apache
Aries JPA support to publish entity manager factories and to enlist into JTA
 transactions. I've abandoned JEE since a while now - am even moving away
from Spring

I've also used XML before but I've recently moved to JSON. JSON is more
compact and also very easy to visualize in a web GUI. However, I store the
JSON in a database and I was hoping to use JPA for this - and also to have
the audit logging take place in the original transaction. If a roll back
occurs I do not want a false audit logging to take place.

/Bengt

2011/7/7 Jari Fredriksson ja...@iki.fi


 How is your JPA accessed? I have done JPA, and Audit logging on top of
 it, but it was into XML files, and performed in a EJB3 Session Bean. The
 JPA objects were plain simple, but they were all accessed via a Session
 Bean Facade. I did it with XML because boss wanted so, but could have
 been database as well.

 7.7.2011 19:49, Bengt Rodehav kirjoitti:
  I actually use the same approach as Hades for createdBy, updatedBy,
  createdWhen and updatedWhen. In addition to this basic audit logging I
 also
  want to log all historical versions together with information about who
  updated the object.
 
  I've read a little bit about Envers. I didn't want to bring it up since
 this
  is an OpenJPA mailing list. It does look interesting but I think it
 requires
  Hibernate which I do not intend to go back to. (I'm actually moving away
  from Hibernate). Also, I'm a bit hesitant to store copies of my rows in
  special audit tables since it also means database migration of those
 tables.
  I think serializing the audit log entries and putting them in one column
 is
  a better approach from a maintenance perspective.
 
  But it would be nice if OpenJPA would provide a callback or some
 mechanism
  (even if it's not standard JPA) that would allow further updates/inserts
 in
  a callback.
 
  Are there any such plans?
 
  /Bengt
 
  2011/7/7 Andrew Thompson at2...@columbia.edu
 
  You might take a look at how hades
  (
 
 http://hades.synyx.org/static/2.x/site/org.synyx.hades/reference/html/auditing.html
 )
  does something close to what you're describing.  Or
  http://www.jboss.org/envers
 
  -Andy
 
  On Thu, 2011-07-07 at 15:35 +0100, David Goodenough wrote:
  On Thursday 07 Jul 2011, Bengt Rodehav wrote:
  I'm using OpenJPA for persistence and would like to audit log any
  changes
  made to my entities. I serialize the objects to JSON (with Gson) and
  store
  them in a separate table in the database. Since the audit log needs to
  have
  the correct id's, the audit logging must take place after the entity
  has
  been persisted.
 
  I was hoping I could use the @PostPersist and @PostUpdate life cycle
  callbacks for this. I do seem to have the right information available
  and
  the serialization works fine but I don't know how I can persist my
  audit
  log entries at this point. From what I've read, I'm not allowed to use
  the
  entity manager in a Post lifecycle callback which of course makes
  this
  hard.
 
  What do you recommend? Is there a good place in JPA/OpenJPA where I
  automatically can trigger the storing of an audit log entry as
  described
  above. Of course I can move this logic up from the persistence layer
 to
  a
  place where I can first have the entity manager persist my entity and
  then
  explicitly call another service to do the audit log. However, this is
 a
  pretty general mechanism that I would like to have automatic support
  for in
  my framework which is why I would like to have it pushed down into the
  persistence layer.
 
  Any ideas?
 
  /Bengt
  You could of course cheat.
 
  While you can not access the entiry manager, there is nothing to stop
 you
  using JDBC.  It would probably not be a good idea to access a table
 that
  JPA is using, but if this audit trail is write only for this app and
 only
  read elsewhere that would solve the problem.
 
  David
 
 
 


 --

 Q:  What's the difference betweeen USL and the Graf Zeppelin?
 A:  The Graf Zeppelin represented cutting edge technology for its time.




Re: Audit log with OpenJPA

2011-07-07 Thread Bengt Rodehav
Wow - lots of discussion here. I must have hit a good topic for once...

I don't see why you shouldn't be proud of your solution. Storing all
versions is a well known idiom for preserving your history. Basically you
don't allow updates but create new versions all the time instead. I have
considered it but I'm a bit afraid for the performance impact since
performance is critical.

I've never done this with JPA though. I guess from your mail that it's not
that straight forward. Ideally what you would like is of course to have a
composit key consisting of the id and version together. On every update a
new instance would be persisted with the same id but a higher version.

I don't think the existing version should be updated at all. I would prefer
just creating a new version and leaving the previous (all the previous
versions) intact. Doesn't JPA allow you to do this?

/Bengt

2011/7/7 No1UNo je...@jerrycarter.org

 Bengt:

 I'm enjoying this discussion because of the gymnastics that were required
 for my solutions.  There is no easy way that I am aware of -- but I would
 LOVE to be wrong.

 Here's what I did (and, no, I'm not particularly proud of the solution):

 (1) For the primary entities, add tracking data (timestamp, user, etc.)
 plus an entityID.
 (2) On an update,
* clone the data in the entity and update the tracking data.  Copy
 the old entityID.
* mark the previous entity as out-of-date (to speed up searches)
* persist both entities
 (3) On an insert,
* persist the new entity and increment the entityID
 (4) Update the queries to extract only those records where the
 'out-of-date' flag was not set.

 This results in both current and historical entities being preserved in the
 same table.  This will reduce performance as the indices are larger than are
 necessary for daily operation.  This solution can be combined with a nightly
 script which moves out-of-date records from the main table to archived
 tables.

 The entity copy is a real pain but seems to be necessary.  See the 'How to
 persist duplicate of an entity?' thread from January 2011.  As I wrote
 earlier:

  I would _love_ to have function that would 'reset' a detached entity.
  Perhaps something like
 
em.detach(myObj);  // ensure that the entity has been detached.
OpenJPAEntityManager kem = OpenJPAPersistence.cast(em);
kem.reset(myObj);
 
  with the result of the 'reset' operation being a class which is again
 virgin, i.e.
 
myObj.id == 0
myObj.version = 0
myObj.pcDetachedState == null
myObj.pcStateManager == null
 
  and so forth for any children.


 This would greatly simplify the cloning process.

 -=- Jerry





 On Jul 7, 2011, at 12:50 PM, Bengt Rodehav [via OpenJPA] wrote:

  I actually use the same approach as Hades for createdBy, updatedBy,
  createdWhen and updatedWhen. In addition to this basic audit logging I
 also
  want to log all historical versions together with information about who
  updated the object.
 
  I've read a little bit about Envers. I didn't want to bring it up since
 this
  is an OpenJPA mailing list. It does look interesting but I think it
 requires
  Hibernate which I do not intend to go back to. (I'm actually moving away
  from Hibernate). Also, I'm a bit hesitant to store copies of my rows in
  special audit tables since it also means database migration of those
 tables.
  I think serializing the audit log entries and putting them in one column
 is
  a better approach from a maintenance perspective.
 
  But it would be nice if OpenJPA would provide a callback or some
 mechanism
  (even if it's not standard JPA) that would allow further updates/inserts
 in
  a callback.
 
  Are there any such plans?
 
  /Bengt
 
  2011/7/7 Andrew Thompson [hidden email]
 
   You might take a look at how hades
   (
  
 http://hades.synyx.org/static/2.x/site/org.synyx.hades/reference/html/auditing.html
 )
   does something close to what you're describing.  Or
   http://www.jboss.org/envers
  
   -Andy
  
   On Thu, 2011-07-07 at 15:35 +0100, David Goodenough wrote:
On Thursday 07 Jul 2011, Bengt Rodehav wrote:
 I'm using OpenJPA for persistence and would like to audit log any
   changes
 made to my entities. I serialize the objects to JSON (with Gson)
 and
   store
 them in a separate table in the database. Since the audit log needs
 to
   have
 the correct id's, the audit logging must take place after the
 entity
   has
 been persisted.

 I was hoping I could use the @PostPersist and @PostUpdate life
 cycle
 callbacks for this. I do seem to have the right information
 available
   and
 the serialization works fine but I don't know how I can persist my
   audit
 log entries at this point. From what I've read, I'm not allowed to
 use
   the
 entity manager in a Post lifecycle callback which of course makes
   this
 hard.

 What do you recommend? Is there a good place in 

Re: Audit log with OpenJPA

2011-07-07 Thread Bengt Rodehav
Again an interesting approach. It's very similar to the way we did it in the
old days (before O/R mappers were abundant). We rolled our own O/R mapping
and also compared the previous state with the new state and saved the
difference (XML in the database). I guess the same approach can be taken if
OpenJPA internals are utilized.

This time I was not going to bother determining the difference but store the
whole object in a serialized form. Thus, my problem is just how to being
able to store the serialized form in the database.

Thanks,

/Bengt

2011/7/7 Pinaki Poddar ppod...@apache.org

 Hi,
  Good to see lot of new ideas about auditing.
  Here is one more [1] that uses OpenJPA specific internals of accessing the
 original state of an entity.
 The comparison of the current state and original state to decide upon the
 audit message is provided trivially in this example -- but at the level at
 which OpenJPA API is being accessed here, much more facilities are
 available
 to compute the 'delta'.

 [1]
 http://webspherepersistence.blogspot.com/2009/01/auditing-with-openjpa.html

 -
 Pinaki
 --
 View this message in context:
 http://openjpa.208410.n2.nabble.com/Audit-log-with-OpenJPA-tp6557932p6559730.html
 Sent from the OpenJPA Users mailing list archive at Nabble.com.



Re: Audit log with OpenJPA

2011-07-07 Thread Bengt Rodehav
Again an interesting solution. Although, as I wrote previously, I intend to
store the whole object and therefore don't need to keep track of what has
changed. I intend to do a JSON diff when viewing the audit log in the GUI
instead.

Your approach does, however, very elegantly solve the problem of how to
store the audit log in the database with JPA since you actually store it in
the object itself.

/Bengt

2011/7/7 Mark Struberg strub...@yahoo.de

 Hi Folks!

 I also use auditing with OpenJPA:
 http://struberg.wordpress.com/2010/07/31/howto-changelog-with-jpa/

 but it currently only works with a patched OpenJPA 2.2.x version.
 https://issues.apache.org/jira/browse/OPENJPA-1873

 We fixed a few parts already, but the POST_LOAD_ON_MERGE isn't yet
 submitted since we didn't quite agree if it is spec conform.

 LieGrue,
 strub


 --- On Thu, 7/7/11, Pinaki Poddar ppod...@apache.org wrote:

  From: Pinaki Poddar ppod...@apache.org
  Subject: Re: Audit log with OpenJPA
  To: users@openjpa.apache.org
  Date: Thursday, July 7, 2011, 7:58 PM
  Hi,
Good to see lot of new ideas about auditing.
Here is one more [1] that uses OpenJPA specific
  internals of accessing the
  original state of an entity.
  The comparison of the current state and original state to
  decide upon the
  audit message is provided trivially in this example -- but
  at the level at
  which OpenJPA API is being accessed here, much more
  facilities are available
  to compute the 'delta'.
 
  [1]
 
 http://webspherepersistence.blogspot.com/2009/01/auditing-with-openjpa.html
 
  -
  Pinaki
  --
  View this message in context:
 http://openjpa.208410.n2.nabble.com/Audit-log-with-OpenJPA-tp6557932p6559730.html
  Sent from the OpenJPA Users mailing list archive at
  Nabble.com.
 



Re: Audit log with OpenJPA

2011-07-07 Thread Pinaki Poddar
 you actually store it in the object itself. 
That's right. This allows in-memory rollback.

Given that the entire 'clean' or 'original' state is available in the
technique I described, the application can make several decisions on 
a) what should be logged in an audit trail -- the entire object in a
separate database/schema, a serialized blob or a JSON stream or whatever.
b) because the technique is based on OpenJPA internal, if an application
decides to take the 'blue pill', then it can simply ask the managed object
which fields have been 'dirtied' if it requires to compute delta
efficiently.

Another related but separate point:
I have noticed lot of requests/annoyance from the users on the limitation of
callback listener methods having no access to the persistence context.
Again, in OpenJPA runtime, the managed entity does know its persistence
context. If the application is ready for a OpenJPA-specific  cast, then the
handle to the persistence context is right there in the entity.

-
Pinaki 
--
View this message in context: 
http://openjpa.208410.n2.nabble.com/Audit-log-with-OpenJPA-tp6557932p6560548.html
Sent from the OpenJPA Users mailing list archive at Nabble.com.


Re: Audit log with OpenJPA

2011-07-07 Thread Pinaki Poddar
 However, I store the JSON in a database and I was hoping to use JPA for
this 

Actually, storing JSON in relational database would not permit query based
on property values. But OpenJPA can provide JSON formatted-data for any web
UI. 

To more about t, following references can help

[1] http://www.ibm.com/developerworks/java/library/j-jest/?ca=drs-
[2] http://openjpa.apache.org/jest
[3]
https://www.ibm.com/developerworks/mydeveloperworks/blogs/pinaki/tags/jest?lang=en
   

-
Pinaki 
--
View this message in context: 
http://openjpa.208410.n2.nabble.com/Audit-log-with-OpenJPA-tp6557932p6560732.html
Sent from the OpenJPA Users mailing list archive at Nabble.com.