| <?xml version="1.0" encoding="UTF-8"?> |
| <!-- |
| Licensed to the Apache Software Foundation (ASF) under one |
| or more contributor license agreements. See the NOTICE file |
| distributed with this work for additional information |
| regarding copyright ownership. The ASF licenses this file |
| to you under the Apache License, Version 2.0 (the |
| "License"); you may not use this file except in compliance |
| with the License. You may obtain a copy of the License at |
| |
| http://www.apache.org/licenses/LICENSE-2.0 |
| |
| Unless required by applicable law or agreed to in writing, |
| software distributed under the License is distributed on an |
| "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| KIND, either express or implied. See the License for the |
| specific language governing permissions and limitations |
| under the License. |
| --> |
| <chapter id="ref_guide_logging"> |
| <title> |
| Logging and Auditing |
| </title> |
| <indexterm zone="ref_guide_logging"> |
| <primary> |
| logging |
| </primary> |
| </indexterm> |
| <indexterm zone="ref_guide_logging"> |
| <primary> |
| Log |
| </primary> |
| </indexterm> |
| <para> |
| Logging is an important means of gaining insight into your application's runtime |
| behavior. OpenJPA provides a flexible logging system that integrates with many |
| existing runtime systems, such as application servers and servlet runners. |
| </para> |
| <para> |
| There are five built-in logging plugins: a |
| <link linkend="ref_guide_logging_openjpa">default logging framework</link> that |
| covers most needs, a <link linkend="ref_guide_logging_log4j"> Log4J</link> |
| delegate, a <link linkend="ref_guide_logging_slf4j"> SLF4J</link> |
| delegate, an <link linkend="ref_guide_logging_commons"> Apache Commons Logging |
| </link> delegate, and a <link linkend="ref_guide_logging_noop">no-op</link> |
| implementation for disabling logging. |
| </para> |
| <warning> |
| <para> |
| Logging can have a negative impact on performance. Disable verbose logging (such |
| as logging of SQL statements) before running any performance tests. It is |
| advisable to limit or disable logging for a production system. You can disable |
| logging altogether by setting the <literal>openjpa.Log</literal> property to |
| <literal>none</literal>. |
| </para> |
| </warning> |
| <section id="ref_guide_logging_channels"> |
| <title> |
| Logging Channels |
| </title> |
| <indexterm zone="ref_guide_logging_channels"> |
| <primary> |
| logging |
| </primary> |
| <secondary> |
| channels |
| </secondary> |
| </indexterm> |
| <para> |
| Logging is done over a number of <emphasis>logging channels</emphasis>, each of |
| which has a <emphasis>logging level</emphasis> which controls the verbosity of |
| log messages recorded for the channel. OpenJPA uses the following logging |
| channels: |
| </para> |
| <itemizedlist> |
| <listitem> |
| <para> |
| <literal>openjpa.Tool</literal>: Messages issued by the OpenJPA command line |
| and Ant tools. Most messages are basic statements detailing which classes or |
| files the tools are running on. Detailed output is only available via the |
| logging category the tool belongs to, such as <literal>openjpa.Enhance</literal> |
| for the enhancer (see <xref linkend="ref_guide_pc_enhance"/>) or <literal> |
| openjpa.MetaData</literal> for the mapping tool (see |
| <xref linkend="ref_guide_mapping_mappingtool"/>). This logging category |
| is provided so that you can get a general idea of what a tool is doing without |
| having to manipulate logging settings that might also affect runtime behavior. |
| </para> |
| </listitem> |
| <listitem> |
| <para> |
| <indexterm> |
| <primary> |
| enhancement |
| </primary> |
| <secondary> |
| log messages |
| </secondary> |
| </indexterm> |
| <literal>openjpa.Enhance</literal>: Messages pertaining to enhancement and |
| runtime class generation. |
| </para> |
| </listitem> |
| <listitem> |
| <para> |
| <indexterm> |
| <primary> |
| metadata |
| </primary> |
| <secondary> |
| log messages |
| </secondary> |
| </indexterm> |
| <literal>openjpa.MetaData</literal>: Details about the generation of metadata |
| and object-relational mappings. |
| </para> |
| </listitem> |
| <listitem> |
| <para> |
| <literal>openjpa.Runtime</literal>: General OpenJPA runtime messages. |
| </para> |
| </listitem> |
| <listitem> |
| <para> |
| <indexterm> |
| <primary> |
| Query |
| </primary> |
| <secondary> |
| log messages |
| </secondary> |
| </indexterm> |
| <literal>openjpa.Query</literal>: Messages about queries. Query strings and any |
| parameter values, if applicable, will be logged to the <literal>TRACE</literal> |
| level at execution time. Information about possible performance concerns will be |
| logged to the <literal>INFO</literal> level. |
| </para> |
| </listitem> |
| <listitem> |
| <para> |
| <indexterm> |
| <primary> |
| caching |
| </primary> |
| <secondary> |
| log messages |
| </secondary> |
| </indexterm> |
| <literal>openjpa.DataCache</literal>: Messages from the L2 data cache plugins. |
| </para> |
| </listitem> |
| <listitem> |
| <para> |
| <indexterm> |
| <primary> |
| JDBC |
| </primary> |
| <secondary> |
| log messages |
| </secondary> |
| </indexterm> |
| <literal>openjpa.jdbc.JDBC</literal>: JDBC connection information. General JDBC |
| information will be logged to the <literal>TRACE</literal> level. Information |
| about possible performance concerns will be logged to the <literal>INFO |
| </literal> level. |
| </para> |
| </listitem> |
| <listitem> |
| <para> |
| <indexterm> |
| <primary> |
| SQL |
| </primary> |
| <secondary> |
| log messages |
| </secondary> |
| </indexterm> |
| <literal>openjpa.jdbc.SQL</literal>: This is the most common logging channel to |
| use. Detailed information about the execution of SQL statements will be sent to |
| the <literal>TRACE</literal> level. It is useful to enable this channel if you |
| are curious about the exact SQL that OpenJPA issues to the datastore. |
| <note> |
| The SQL issued to the database may contain sensitive information. By default the |
| parameter values used in the prepared statements generated by OpenJPA will not |
| be printed in the SQL log - instead you will see a ? for each value. The actual |
| values may be printed by adding <literal>PrintParameters=True</literal> to the |
| <link linkend="openjpa.ConnectionFactoryProperties"> |
| <literal>openjpa.ConnectionFactoryProperties</literal></link> property. Also |
| see <link linkend="ref_guide_dbsetup_builtin"><literal>Using the OpenJPA |
| DataSource</literal></link> |
| </note> |
| </para> |
| <para> |
| When using the built-in OpenJPA logging facilities, you can enable SQL logging |
| by adding <literal>SQL=TRACE</literal> to your <literal>openjpa.Log</literal> |
| property. |
| </para> |
| <para> |
| OpenJPA can optionally reformat the logged SQL to make it easier to read. To |
| enable pretty-printing, add <literal>PrettyPrint=true</literal> to the |
| <link linkend="openjpa.ConnectionFactoryProperties"><literal> |
| openjpa.ConnectionFactoryProperties</literal></link> property. You can control |
| how many columns wide the pretty-printed SQL will be with the <literal> |
| PrettyPrintLineLength</literal> property. The default line length is 60 columns. |
| </para> |
| <para> |
| While pretty printing makes things easier to read, it can make output harder to |
| process with tools like grep. |
| </para> |
| <para> |
| Pretty-printing properties configuration might look like so: |
| </para> |
| <programlisting> |
| <property name="openjpa.Log" value="SQL=TRACE"/> |
| <property name="openjpa.ConnectionFactoryProperties" |
| value="PrettyPrint=true, PrettyPrintLineLength=72"/> |
| </programlisting> |
| </listitem> |
| <listitem> |
| <para> |
| <indexterm> |
| <primary> |
| SQLDiag |
| </primary> |
| <secondary> |
| log messages |
| </secondary> |
| </indexterm> |
| <literal>openjpa.jdbc.SQLDiag</literal>: This logging channel provides additional |
| information about entity actitvies such as create, find, update or delete, and eager |
| loading of relation or field properties. If you enable this channel, it is recommended |
| that <literal>openjpa.jdbc.SQL</literal> channel is also enabled. |
| The additional trace can help you relate the entity activities to the execution of |
| SQL statements that OpenJPA issued to the datastore. |
| </para> |
| <para> |
| When using the built-in OpenJPA logging facilities, you can enable SQLDiag logging |
| by adding <literal>SQLDiag=TRACE</literal> to your <literal>openjpa.Log</literal> |
| property. |
| </para> |
| </listitem> |
| <listitem> |
| <para> |
| <indexterm> |
| <primary> |
| schema |
| </primary> |
| <secondary> |
| log messages |
| </secondary> |
| </indexterm> |
| <literal>openjpa.jdbc.Schema</literal>: Details about operations on the |
| database schema. |
| </para> |
| </listitem> |
| </itemizedlist> |
| </section> |
| <section id="ref_guide_logging_openjpa"> |
| <title> |
| OpenJPA Logging |
| </title> |
| <indexterm zone="ref_guide_logging_openjpa"> |
| <primary> |
| logging |
| </primary> |
| <secondary> |
| default |
| </secondary> |
| </indexterm> |
| <para> |
| By default, OpenJPA uses a basic logging framework with the following output |
| format: |
| </para> |
| <para> |
| <literal>millis</literal> <literal>diagnostic context</literal> <literal>level</literal> [<literal>thread name</literal>] <literal>channel</literal> - <literal>message</literal> |
| </para> |
| <para> |
| For example, when loading an application that uses OpenJPA, a message like the |
| following will be sent to the <literal>openjpa.Runtime</literal> channel: |
| </para> |
| <programlisting> |
| 2107 INFO [main] openjpa.Runtime - Starting OpenJPA 2.2.0 |
| </programlisting> |
| <para> |
| The default logging system accepts the following parameters: |
| </para> |
| <itemizedlist> |
| <listitem> |
| <para> |
| <literal>File</literal>: The name of the file to log to, or <literal>stdout |
| </literal> or <literal>stderr</literal> to send messages to standard out and |
| standard error, respectively. By default, OpenJPA sends log messages to standard |
| error. |
| </para> |
| </listitem> |
| <listitem> |
| <para> |
| <literal>DefaultLevel</literal>: The default logging level of unconfigured |
| channels. Recognized values are <literal>TRACE, INFO, WARN, ERROR </literal> |
| and <literal>FATAL</literal>. Defaults to <literal>INFO</literal>. |
| </para> |
| </listitem> |
| <listitem> |
| <para> |
| <literal>DiagnosticContext</literal>: A string that will be prepended to all |
| log messages. If this is not supplied and an <literal>openjpa.Id</literal> |
| property value is available, that value will be used. |
| </para> |
| </listitem> |
| <listitem> |
| <para> |
| <literal><channel></literal>: Using the last token of the |
| <link linkend="ref_guide_logging_channels">logging channel</link> name, you can |
| configure the log level to use for that channel. See the examples below. |
| </para> |
| </listitem> |
| </itemizedlist> |
| <example id="ref_guide_logging_openjpa_std_ex"> |
| <title> |
| Standard OpenJPA Log Configuration |
| </title> |
| <programlisting> |
| <property name="openjpa.Log" value="DefaultLevel=WARN, Runtime=INFO, Tool=INFO"/> |
| </programlisting> |
| </example> |
| <example id="ref_guide_logging_openjpa_sql_ex"> |
| <title> |
| Standard OpenJPA Log Configuration + All SQL Statements |
| </title> |
| <programlisting> |
| <property name="openjpa.Log" value="DefaultLevel=WARN, Runtime=INFO, Tool=INFO, SQL=TRACE"/> |
| </programlisting> |
| </example> |
| <example id="ref_guide_logging_openjpa_file"> |
| <title> |
| Logging to a File |
| </title> |
| <programlisting> |
| <property name="openjpa.Log" value="File=/tmp/org.apache.openjpa.log, DefaultLevel=WARN, Runtime=INFO, Tool=INFO"/> |
| </programlisting> |
| </example> |
| </section> |
| <section id="ref_guide_logging_noop"> |
| <title> |
| Disabling Logging |
| </title> |
| <indexterm zone="ref_guide_logging_noop"> |
| <primary> |
| logging |
| </primary> |
| <secondary> |
| disabling |
| </secondary> |
| </indexterm> |
| <para> |
| Disabling logging can be useful to analyze performance without any I/O overhead |
| or to reduce verbosity at the console. To do this, set the <literal>openjpa.Log |
| </literal> property to <literal>none</literal>. |
| </para> |
| <para> |
| Disabling logging permanently, however, will cause all warnings to be consumed. |
| We recommend using one of the more sophisticated mechanisms described in this |
| chapter. |
| </para> |
| </section> |
| <section id="ref_guide_logging_log4j"> |
| <title> |
| Log4J |
| </title> |
| <indexterm zone="ref_guide_logging_log4j"> |
| <primary> |
| logging |
| </primary> |
| <secondary> |
| Log4j |
| </secondary> |
| </indexterm> |
| <para> |
| When <literal>openjpa.Log</literal> is set to <literal>log4j</literal>, OpenJPA |
| will delegate to Log4J for logging. In a standalone application, Log4J logging |
| levels are controlled by a resource named <filename>log4j.properties</filename> |
| , which should be available as a top-level resource (either at the top level of |
| a jar file, or in the root of one of the <literal>CLASSPATH</literal> |
| directories). When deploying to a web or EJB application server, Log4J |
| configuration is often performed in a <filename>log4j.xml</filename> file |
| instead of a properties file. For further details on configuring Log4J, please |
| see the <ulink url="http://logging.apache.org/log4j/1.2/manual.html">Log4J |
| Manual</ulink>. We present an example <filename>log4j.properties</filename> file |
| below. |
| </para> |
| <example id="ref_guide_logging_log4j_ex"> |
| <title> |
| Standard Log4J Logging |
| </title> |
| <programlisting> |
| log4j.rootCategory=WARN, console |
| log4j.category.openjpa.Tool=INFO |
| log4j.category.openjpa.Runtime=INFO |
| log4j.category.openjpa.Remote=WARN |
| log4j.category.openjpa.DataCache=WARN |
| log4j.category.openjpa.MetaData=WARN |
| log4j.category.openjpa.Enhance=WARN |
| log4j.category.openjpa.Query=WARN |
| log4j.category.openjpa.jdbc.SQL=WARN |
| log4j.category.openjpa.jdbc.SQLDiag=WARN |
| log4j.category.openjpa.jdbc.JDBC=WARN |
| log4j.category.openjpa.jdbc.Schema=WARN |
| |
| log4j.appender.console=org.apache.log4j.ConsoleAppender |
| </programlisting> |
| </example> |
| </section> |
| <section id="ref_guide_logging_commons"> |
| <title> |
| Apache Commons Logging |
| </title> |
| <indexterm zone="ref_guide_logging_commons"> |
| <primary> |
| logging |
| </primary> |
| <secondary> |
| Apache Commons |
| </secondary> |
| </indexterm> |
| <para> |
| Set the <literal>openjpa.Log</literal> property to <literal>commons</literal> to |
| use the <ulink url="http://commons.apache.org/logging/"> Apache |
| Commons Logging</ulink> thin library for issuing log messages. The |
| Commons Logging library act as a wrapper around a number of popular logging |
| APIs, including the |
| <ulink url="http://logging.apache.org/log4j/1.2/index.html"> Jakarta Log4J |
| </ulink> project, and the native |
| <ulink url="http://download.oracle.com/javase/6/docs/api/java/util/logging/package-summary.html"> |
| java.util.logging</ulink> package in JDK. |
| </para> |
| <para> |
| When using the Commons Logging framework in conjunction with Log4J, |
| configuration will be the same as was discussed in the Log4J section above. |
| </para> |
| <section id="ref_guide_logging_jdk14"> |
| <title> |
| JDK java.util.logging |
| </title> |
| <indexterm zone="ref_guide_logging_jdk14"> |
| <primary> |
| logging |
| </primary> |
| <secondary> |
| JDK |
| </secondary> |
| </indexterm> |
| <para> |
| When using JDK logging in conjunction with OpenJPA's Commons Logging |
| support, logging will proceed through Java's built-in logging provided by the |
| <ulink url="http://download.oracle.com/javase/6/docs/api/java/util/logging/package-summary.html"> |
| java.util.logging</ulink> package. For details on configuring the built-in |
| logging system, please see the |
| <ulink url="http://download.oracle.com/javase/6/docs/technotes/guides/logging/overview.html"> |
| Java Logging Overview</ulink>. |
| </para> |
| <para> |
| By default, JDK's logging package looks in the <filename> |
| JAVA_HOME/lib/logging.properties</filename> file for logging configuration. This |
| can be overridden with the <literal>java.util.logging.config.file</literal> |
| system property. For example: |
| </para> |
| <programlisting> |
| java -Djava.util.logging.config.file=mylogging.properties com.company.MyClass |
| </programlisting> |
| <example id="ref_guide_logging_jdk14_propfile"> |
| <title> |
| JDK Log Properties |
| </title> |
| <programlisting> |
| # specify the handlers to create in the root logger |
| # (all loggers are children of the root logger) |
| # the following creates two handlers |
| handlers=java.util.logging.ConsoleHandler, java.util.logging.FileHandler |
| |
| # set the default logging level for the root logger |
| .level=ALL |
| |
| # set the default logging level for new ConsoleHandler instances |
| java.util.logging.ConsoleHandler.level=INFO |
| |
| # set the default logging level for new FileHandler instances |
| java.util.logging.FileHandler.level=ALL |
| |
| # set the default formatter for new ConsoleHandler instances |
| java.util.logging.ConsoleHandler.formatter=java.util.logging.SimpleFormatter |
| |
| # set the default logging level for all OpenJPA logs |
| openjpa.Tool.level=INFO |
| openjpa.Runtime.level=INFO |
| openjpa.Remote.level=INFO |
| openjpa.DataCache.level=INFO |
| openjpa.MetaData.level=INFO |
| openjpa.Enhance.level=INFO |
| openjpa.Query.level=INFO |
| openjpa.jdbc.SQL.level=INFO |
| openjpa.jdbc.SQLDiag.level=INFO |
| openjpa.jdbc.JDBC.level=INFO |
| openjpa.jdbc.Schema.level=INFO |
| </programlisting> |
| </example> |
| </section> |
| </section> |
| <section id="ref_guide_logging_slf4j"> |
| <title> |
| SLF4J |
| </title> |
| <indexterm zone="ref_guide_logging_slf4j"> |
| <primary> |
| logging |
| </primary> |
| <secondary> |
| SLF4j |
| </secondary> |
| </indexterm> |
| <para> |
| When <literal>openjpa.Log</literal> is set to <literal>slf4j</literal>, OpenJPA |
| will delegate to SLF4J API for logging, which provides several adapters or |
| a simple logging mechanism. For further details on logging adapters and |
| configuring SLF4J, please see the |
| <ulink url="http://www.slf4j.org/manual.html">SLF4J website</ulink>. |
| </para> |
| <para> |
| Note, as SLF4J does not provide a <literal>FATAL</literal> log level the |
| <literal>SLF4JLogFactory</literal> will map it to the <literal>ERROR</literal> |
| log level. |
| </para> |
| </section> |
| <section id="ref_guide_logging_custom"> |
| <title> |
| Custom Log |
| </title> |
| <indexterm zone="ref_guide_logging_custom"> |
| <primary> |
| logging |
| </primary> |
| <secondary> |
| custom |
| </secondary> |
| </indexterm> |
| <para> |
| If none of available logging systems meet your needs, you can configure the |
| logging system with a custom logger. You might use custom logging to integrate |
| with a proprietary logging framework used by some applications servers, or for |
| logging to a graphical component for GUI applications. |
| </para> |
| <para> |
| A custom logging framework must include an implementation of the |
| <ulink url="../../apidocs/org/apache/openjpa/lib/log/LogFactory.html"><classname> |
| org.apache.openjpa.lib.log.LogFactory</classname></ulink> interface. We present |
| a custom <classname>LogFactory</classname> below. |
| </para> |
| <example id="ref_guide_logging_custom_ex"> |
| <title> |
| Custom Logging Class |
| </title> |
| <programlisting> |
| package com.xyz; |
| |
| import org.apache.openjpa.lib.log.*; |
| |
| public class CustomLogFactory |
| implements LogFactory { |
| |
| private String _prefix = "CUSTOM LOG"; |
| |
| public void setPrefix(String prefix) { |
| _prefix = prefix; |
| } |
| |
| public Log getLog(String channel) { |
| // Return a simple extension of AbstractLog that will log |
| // everything to the System.err stream. Note that this is |
| // roughly equivalent to OpenJPA's default logging behavior. |
| return new AbstractLog() { |
| |
| protected boolean isEnabled(short logLevel) { |
| // log all levels |
| return true; |
| } |
| |
| protected void log(short type, String message, Throwable t) { |
| // just send everything to System.err |
| System.err.println(_prefix + ": " + type + ": " |
| + message + ": " + t); |
| } |
| }; |
| } |
| } |
| </programlisting> |
| </example> |
| <para> |
| To make OpenJPA use your custom log factory, set the |
| <link linkend="openjpa.Log"><literal>openjpa.Log</literal></link> configuration |
| property to your factory's full class name. Because this property is a plugin |
| property (see <xref linkend="ref_guide_conf_plugins"/> ), you can also |
| pass parameters to your factory. For example, to use the example factory above |
| and set its prefix to "LOG MSG", you would set the <literal>openjpa.Log |
| </literal> property to the following string: |
| </para> |
| <programlisting> |
| 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> |
| @jakarta.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> |