You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@openjpa.apache.org by pp...@apache.org on 2011/08/25 03:08:14 UTC
svn commit: r1161350 -
/openjpa/trunk/openjpa-project/src/doc/manual/ref_guide_logging.xml
Author: ppoddar
Date: Thu Aug 25 01:08:14 2011
New Revision: 1161350
URL: http://svn.apache.org/viewvc?rev=1161350&view=rev
Log:
OPENJPA-2030: Audit documentation
Modified:
openjpa/trunk/openjpa-project/src/doc/manual/ref_guide_logging.xml
Modified: openjpa/trunk/openjpa-project/src/doc/manual/ref_guide_logging.xml
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-project/src/doc/manual/ref_guide_logging.xml?rev=1161350&r1=1161349&r2=1161350&view=diff
==============================================================================
--- openjpa/trunk/openjpa-project/src/doc/manual/ref_guide_logging.xml (original)
+++ openjpa/trunk/openjpa-project/src/doc/manual/ref_guide_logging.xml Thu Aug 25 01:08:14 2011
@@ -19,7 +19,7 @@
-->
<chapter id="ref_guide_logging">
<title>
- Logging
+ Logging and Auditing
</title>
<indexterm zone="ref_guide_logging">
<primary>
@@ -605,4 +605,101 @@ and set its prefix to "LOG MSG", you wou
com.xyz.CustomLogFactory(Prefix="LOG MSG")
</programlisting>
</section>
+
+
+<section id="ref_guide_audit">
+ <title>OpenJPA Audit</title>
+ Transactional applications often require to audit changes in persistent objects.
+ OpenJPA can enable audit facility for all persistent entities in few simple steps.
+ <section>
+ <title>Configuration</title>
+ <para><emphasis>Annotate Persistent Entity</emphasis>
+ Any persistence entity can be enabled for audit by annotating with
+ <literal>org.apache.openjpa.audit.Auditable</literal>.
+ </para>
+ <programlisting>
+ @javax.persistence.Entity
+ @org.apache.openjpa.audit.Auditable
+ public class MyDomainObject { ...}
+ </programlisting>
+ <para>
+ This <literal>Auditable</literal> annotation enables auditing of creation, update or delete of
+ <literal>MyDomainObject</literal> instances. The <literal>Auditable</literal> annotation accepts
+ list of enumerated values <literal>org.apache.openjpa.audit.AuditableOperation</literal> namely
+ <literal>CREATE</literal>, <literal>UPDATE</literal> and <literal>DELETE</literal> to customize
+ only appropriate operations be audited. By deafult, all of the above operations are audited.
+ </para>
+ <para><emphasis>Configure Persistence Configuration</emphasis>
+ The audit facility is invoked at runtime via configuration of <literal>META-INF/persistence.xml</literal>.
+ The following property configures auditing via a default auditor
+ </para>
+ <programlisting><property name="openjpa.Auditor" value="default"/></programlisting>
+ <para>
+ The default auditor does not do much. It simply prints each auditable instance with its latest and original
+ states on a standard console (or to a designated file).
+ </para>
+ <para>The <emphasis>latest</emphasis> state of an instance designates the state which is commited to the
+ database.
+ The <emphasis>original</emphasis>state designates the state when the instance entered the managed persistent
+ context. For example, when a new instance is persisted or a existing instance is loaded from the database.
+ </para>
+ </section>
+ <section>
+ <title>Developing custom auditing</title>
+
+ <para>
+ For real use case, an application will prefer more than printing the changed instances. The application, in
+ such case, needs to implement <literal>org.apache.openjpa.audit.Auditor</literal> interface.
+ This simple interface has the following method:
+ </para>
+ <programlisting>
+ /**
+ * OpenJPA runtime will invoke this method with the given parameters
+ * within a transaction.
+ *
+ * @param broker the active persistence context.
+ * @param newObjects the set of auditable objects being created. Can be empty, but never null.
+ * @param updates the set of auditable objects being updated. Can be empty, but never null.
+ * @param deletes the set of auditable objects being deleted. Can be empty, but never null.
+ */
+ public void audit(Broker broker, Collection<Audited> newObjects, Collection<Audited> updates,
+ Collection<Audited> deletes);
+ </programlisting>
+ <para>
+ OpenJPA runtime will invoke this method <emphasis>before</emphasis> database commit. Via this callback method,
+ the application receives
+ the auditable instances in three separate collections of <literal>org.apache.openjpa.audit.Auditable</literal>.
+ An <literal>Auditable</literal> instance provides the latest and original state of a persistent object.
+ The latest object is
+ the same persistent instance to be committed. The original instance is a transient instance holding the
+ original state of the instance when it entered the managed context. The active persistence context
+ is also supplied in this callback method, so that an application may decide to persist the audit log
+ in the same database.
+ </para>
+ <para>
+ It is important to note that the original object can not be persisted in the same transaction, because
+ it has the same persistent identity of the latest object.
+ </para>
+ <para>
+ A single instance of implemented <literal>org.apache.openjpa.audit.Auditor</literal> interface
+ is available for a persistence unit. However, an application's own implementation of this interface
+ need not be thread-safe, because OpenJPA runtime guards against concurrent invocation of the
+ callback method.
+ </para>
+ <para>
+ The <literal>org.apache.openjpa.audit.Auditor</literal> interface is configurable. Hence any bean style
+ getter and setter method on its implementation will be populated as usual for any other OpenJPA plugin.
+ In the following example,
+ </para>
+ <programlisting>
+ <property name="openjpa.Auditor" value="com.acme.Auditor(param2=10,param2='hello')"/>
+ </programlisting>
+ <para>
+ An instance of <literal>com.acme.Auditor</literal> will be instantiated and if it has been style getter and
+ setter methods for <literal>param1</literal> and <literal>param2</literal>, then the respective setters
+ will be called with <literal>10</literal> and <literal>"hello"</literal> before the instance being used.
+ </para>
+ </section>
+
+</section>
</chapter>