OPENJPA-298

git-svn-id: https://svn.apache.org/repos/asf/openjpa/trunk@560342 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Patrick Linskey 2007-07-27 18:18:10 +00:00
parent 8586e0fef3
commit 58533057a0
6 changed files with 189 additions and 87 deletions

View File

@ -177,7 +177,7 @@ constructor.
<para>
OpenJPA's <emphasis>enhancer</emphasis> will automatically add a protected
no-arg constructor to your class when required. Therefore, this restriction does
not apply when using OpenJPA. See <xref linkend="ref_guide_pc_enhance"/>
not apply when using the enhancer. See <xref linkend="ref_guide_pc_enhance"/>
of the Reference Guide for details.
</para>
</note>

View File

@ -222,7 +222,7 @@ information.
<para>
Let's compile the initial classes and see them in action. To do so, we must
compile the <filename>.java</filename> files, as we would with any Java project,
and then pass the resulting classes through the OpenJPA enhancer:
and then optionally pass the resulting classes through the OpenJPA enhancer.
</para>
<note>
<para>
@ -387,7 +387,7 @@ You can use any java compiler instead of <command>javac</command>.
</listitem>
<listitem>
<para>
Enhance the persistent classes.
Enhance the persistent classes. (Optional)
</para>
<programlisting>
java org.apache.openjpa.enhance.PCEnhancer Animal.java Dog.java
@ -396,7 +396,7 @@ java org.apache.openjpa.enhance.PCEnhancer Animal.java Dog.java
This step runs the OpenJPA enhancer on the <filename>Animal.java</filename> and
<filename>Dog.java</filename> files mentioned above. See
<xref linkend="ref_guide_pc_enhance"/> of the Reference Guide for more
information on the enhancer, including how to use automatic runtime enhancement.
information on the enhancer, including alternatives to enhancement.
</para>
<note>
<para>
@ -417,7 +417,7 @@ OpenJPA configuration.
Configuring the Datastore
</title>
<para>
Now that we've compiled the source files and enhanced the persistent classes,
Now that we've compiled the source files,
we're ready to set up the database. <ulink url="http://hsqldb.sourceforge.net">
Hypersonic SQL</ulink>, a pure Java relational database, is included in the
OpenJPA distribution. We have included this database because it is simple to set
@ -819,7 +819,7 @@ javac Rabbit.java
</listitem>
<listitem>
<para>
Enhance the <classname>Rabbit</classname> class.
Enhance the <classname>Rabbit</classname> class. (Optional)
</para>
<programlisting>
java org.apache.openjpa.enhance.PCEnhancer Rabbit.java
@ -907,7 +907,7 @@ javac Snake.java
</listitem>
<listitem>
<para>
Enhance the class.
Enhance the class. (Optional)
</para>
<programlisting>
java org.apache.openjpa.enhance.PCEnhancer Snake.java
@ -1118,7 +1118,7 @@ key that joins the rabbit table to the snake table. The rabbit table has an
<listitem>
<para>
Compile <filename>Snake.java</filename> and <filename>Rabbit.java</filename> and
enhance the classes.
optionally enhance the classes.
</para>
<programlisting>
javac Snake.java Rabbit.java
@ -1320,7 +1320,7 @@ nested <filename>ejb</filename> and <filename>jsp</filename> directories:
javac *.java ejb/*.java jsp/*.java
</programlisting>
<para>
Enhance the Car class.
Enhance the Car class. (Optional)
</para>
<programlisting>
java org.apache.openjpa.enhance.PCEnhancer Car.java

View File

@ -167,6 +167,25 @@ OpenJPAEntityManager.setPopulateDataCache</ulink>
</para>
</entry>
</row>
<row>
<entry colname="name">
<emphasis role="bold">
Run the OpenJPA enhancer on your persistent classes,
either at build-time or deploy-time.
</emphasis>
<para>
<emphasis>performance, scalability, memory footprint</emphasis>
</para>
</entry>
<entry colname="desc">
OpenJPA performs best when your persistent classes have been run through the
OpenJPA post-compilation bytecode enhancer. When dealing with enhanced classes,
OpenJPA can make a number of assumptions that reduce memory footprint and
accelerate persistent data access. When evaluating OpenJPA's performance,
build-time or deploy-time enhancement should be enabled. See
<xref linkend="ref_guide_pc_enhance"/> for details.
</entry>
</row>
<row>
<entry colname="name">
<emphasis role="bold">

View File

@ -114,7 +114,7 @@ any unlisted class is not persistent.
</indexterm>
<para>
In order to provide optimal runtime performance, flexible lazy loading, and
efficient, immediate dirty tracking, OpenJPA uses an <emphasis> enhancer
efficient, immediate dirty tracking, OpenJPA can use an <emphasis>enhancer
</emphasis>. An enhancer is a tool that automatically adds code to your
persistent classes after you have written them. The enhancer post-processes the
bytecode generated by your Java compiler, adding the necessary fields and
@ -139,7 +139,7 @@ the <methodname>getId</methodname> method in your source file.
The diagram above illustrates the compilation of a persistent class.
</para>
<para>
You can add the OpenJPA enhancer to your build process, or use Java 1.5's new
You can add the OpenJPA enhancer to your build process, or use Java 1.5's
instrumentation features to transparently enhance persistent classes when they
are loaded into the JVM. The following sections describe each option.
</para>
@ -269,14 +269,14 @@ class load error, simply re-compile and re-enhance the offending classes.
</tertiary>
</indexterm>
<para>
The JEE 5 specification includes hooks to automatically enhance JPA entities
when they are deployed into a container. Thus, if you are using a JEE
The Java EE 5 specification includes hooks to automatically enhance JPA entities
when they are deployed into a container. Thus, if you are using a Java EE
5-compliant application server, OpenJPA will enhance your entities automatically
at runtime. Note that if you prefer build-time enhancement, OpenJPA's runtime
enhancer will correctly recognize and skip pre-enhanced classes.
</para>
<para>
If your application server does not support the JEE 5 enhancement hooks,
If your application server does not support the Java EE 5 enhancement hooks,
consider using the build-time enhancement described above, or the more general
runtime enhancement described in the next section.
</para>
@ -351,6 +351,20 @@ check whether each class loaded into the JVM is persistent, and enhance it
accordingly. This may slow down class load times significantly.
</para>
</listitem>
<listitem>
<para>
<literal>runtimeEnhancement</literal>: Boolean controlling whether OpenJPA
class enhancement should be available in this JVM execution. Default:
<literal>true</literal>
</para>
</listitem>
<listitem>
<para>
<literal>runtimeRedefinition</literal>: Boolean controlling whether OpenJPA
class redefinition should be available in this JVM execution. Default:
<literal>true</literal>
</para>
</listitem>
</itemizedlist>
<example id="ref_guide_pc_enhance_runtime_opt_ex">
<title>
@ -361,38 +375,107 @@ java -javaagent:/home/dev/openjpa/lib/openjpa.jar=addDefaultConstructor=false co
</programlisting>
</example>
</section>
<section id="ref_guide_pc_enhance_sercompat">
<section id="ref_guide_pc_enhance_unenhanced_types">
<title>
Serializing Enhanced Types
Omitting the OpenJPA enhancer
</title>
<indexterm zone="ref_guide_pc_enhance_sercompat">
<indexterm zone="ref_guide_pc_enhance_unenhanced_types">
<primary>
enhancer
</primary>
<secondary>
serialization
omitting
</secondary>
<tertiary>
of enhanced types
outside a container
</tertiary>
</indexterm>
<indexterm zone="ref_guide_pc_enhance_sercompat">
<primary>
serialization
</primary>
<secondary>
of enhanced types
</secondary>
</indexterm>
<para>
By default, OpenJPA maintains serialization compatibility between the enhanced
and unenhanced versions of a class. This allows you to serialize instances
between a server using OpenJPA and a client that does not have access to
enhanced classes or OpenJPA libraries. In some cases, however, you can make the
persist and attach processes more robust and efficient by allowing breaks in
serialization compatibility. See <xref linkend="ref_guide_detach_graph"/>
for details.
OpenJPA does not require that the enhancer be run. If you do not run the
enhancer, OpenJPA will fall back to one of several possible alternatives for
state tracking, depending on the execution environment.
</para>
<itemizedlist>
<listitem><para>
<emphasis>Deploy-time enhancement</emphasis>: if you are running your
application inside a Java EE 5 container, or another environment that supports
the JPA container contract, then OpenJPA will automatically perform class
transformation at deploy time.
</para></listitem>
<listitem><para>
<emphasis>Java 6 class retransformation</emphasis>: if you are running your
application in a Java 6 environment, OpenJPA will attempt to dynamically
register a <literal>ClassTransformer</literal> that will redefine your
persistent classes on the fly to track access to persistent data. Additionally,
OpenJPA will create a subclass for each of your persistent classes. When
you execute a query or traverse a relation, OpenJPA will return an instance
of the subclass. This means that the <literal>instanceof</literal> operator
will work as expected, but <literal>o.getClass()</literal> will return the
subclass instead of the class that you wrote.
</para>
<para>
You do not need to do anything at all to get this behavior. OpenJPA will
automatically detect whether or not the execution environment is capable of
Java 6 class retransformation.
</para></listitem>
<listitem><para>
<emphasis>Java 5 class redefinition</emphasis>: if you are running your
application in a Java 5 environment, and you specify the OpenJPA javaagent,
OpenJPA will use Java 5 class redefinition to redefine any persistent classes
that are not enhanced by thet OpenJPA javaagent. Aside from the requirement
that you specify a javaagent on the command line, this behavior is exactly the
same as the Java 6 class retransformation behavior. Of course, since the
OpenJPA javaagent performs enhancement by default, this will only be available
if you set the <literal>runtimeEnhancement</literal> javaagent flag to
<literal>false</literal>, or on any classes that are skipped by the OpenJPA
runtime enhancement process for some reason.
</para></listitem>
<listitem><para>
<emphasis>state comparison and subclassing</emphasis>: if you are running
in a Java 5 environment without a javaagent, or in a Java 6 environment that
does not support class retransformation, OpenJPA will still create subclasses
as outlined above. However, in some cases, OpenJPA may not be able to receive
notifications when you read or write persistent data.
</para>
<para>
If you are using <emphasis>property access</emphasis> for your persistent data,
then OpenJPA will be able to track all accesses for instances that you load
from the database, but not for instances that you create. This is because
OpenJPA will create new instances of its dynamically-generated subclass when
it loads data from the database. The dynamically-generated subclass has
code in the setters and getters that notify OpenJPA about persistent data
access. This means that new instances that you create will be subject to
state-comparison checks (see discussion below) to compute which fields to
write to the database, and that OpenJPA will ignore requests to evict
persistent data from such instances. In practice, this is not a particularly
bad limitation, since OpenJPA already knows that it must insert all field
values for new instances. So, this is only really an issue if you flush
changes to the database while inserting new records; after such a flush,
OpenJPA will need to hold potentially-unneeded hard references to the
new-flushed instances.
</para>
<para>
If you are using <emphasis>field access</emphasis> for your persistent data,
then OpenJPA will not be able to track accesses for any instances, including
ones that you load from the database. So, OpenJPA will perform state-comparison
checks to determine which fields are dirty. These state comparison checks are
costly in two ways. First, there is a performance penalty at flush / commit
time, since OpenJPA must walk through every field of every instance to determine
which fields of which records are dirty. Second, there is a memory penalty,
since OpenJPA must hold hard references to all instances that were loaded at
any time in a given transaction, and since OpenJPA must keep a copy of all
the initial values of the loaded data for later comparison. Additionally,
OpenJPA will ignore requests to evict persistent state for these types of
instances. Finally, the default lazy loading configuration will be ignored for
single-valued fields (one-to-one, many-to-one, and any other non-collection
or non-map field that has a lazy loading configuration). If you use fetch
groups or programmatically configure your fetch plan, OpenJPA will obey these
directives, but will be unable to lazily load any data that you exclude from
loading. As a result of these limitations, it is not recommended that you use
field access if you are not either running the enhancer or using OpenJPA with
a javaagent or in a Java 6 environment.
</para></listitem>
</itemizedlist>
</section>
</section>
<section id="ref_guide_pc_oid">

View File

@ -102,7 +102,7 @@ Compile the classes:
<listitem>
<para>
You should then proceed to pass in the configuration file you are using to the
enhancer:
enhancer: (Optional)
</para>
<para>
<userinput>java org.apache.openjpa.enhance.PCEnhancer -p persistence.xml Machine.java Crane.java Bulldozer.java