JPA Class Enhancer
The ObjectDB Enhancer is a post-compilation tool that improves performance by modifying the bytecode of compiled classes. Enhancement applies mainly to user-defined persistable classes (entity classes, embeddable classes, and mapped superclasses) and is usually optional.
However, there is one case where enhancement is required. Non-persistable classes that directly access persistent fields of enhanced classes (not through methods) must also be enhanced. It is a good practice to avoid directly accessing persistent fields of other classes. This practice is required by the JPA specification but not enforced by ObjectDB. Instead, use the accessor and mutator methods of the desired class (for example, the get and set methods). If you follow this practice, only user-defined persistable classes require enhancement.
The enhancer silently ignores any specified class that does not need to be enhanced.
Enhancement improves efficiency in three ways:
- Enhanced code enables efficient tracking of persistent field modifications, which avoids the need for snapshot comparison of entities (as explained in Chapter 3). Special code is added to enhanced classes that automatically notifies ObjectDB whenever a persistent field is modified.
- Enhanced code enables lazy loading of entities. Without enhancement, only persistent collection and map fields can be loaded lazily (by using proxy objects), but persistent fields that reference entities directly (in a one-to-one relationship) must be loaded eagerly.
- Optimized methods are added to enhanced classes as a faster alternative to reflection.
This page covers the following topics:
Command line enhancementMaven and ANT enhancementEnhancement APILoad time (Java agent) enhancementCommand line enhancement
The ObjectDB Enhancer is a Java console application included in the objectdb.jar file.
You can run it from the command line as follows:
$ java -cp objectdb.jar com.objectdb.Enhancer
If objectdb.jar is not in the current directory, a path to the file must be specified.
Alternatively, you can run the Enhancer by using a shell script (enhancer.bat on Windows and enhancer.sh on Unix/Linux) from the ObjectDB bin directory. To use that script, you must edit the paths to the objectdb.jar file and the JVM.
A usage message is displayed if no arguments are specified on the command line:
ObjectDB Enhancer [version 2.9.4] Copyright (c) 2025, ObjectDB Software. All rights reserved. Usage: java com.objectdb.Enhancer [ <options> | <class> | <filename> ] ... <class> - name of a class (without .class suffix) in the CLASSPATH <filename> - path to class or jar file(s), *? wildcards supported <options> include: -cp <dir> : path to input user classes -pu <name> : persistence unit name -s : include sub directories in search -d <dir> : output path for enhanced classes
You can specify class files and JAR files for enhancement explicitly or by using wildcards:
$ java com.objectdb.Enhancer test/*.class Main.class pc.jar
If the -s option is specified, files in subdirectories are also searched and enhanced:
$ java com.objectdb.Enhancer -s "*.class"
The "*.class" expression is enclosed in quotes to prevent the shell from expanding the wildcard.
The output lists the classes that have been enhanced:
[ObjectDB 2.9.4] 3 persistable types have been enhanced: test.MyEntity1 test.MyEntity2 test.MyEmbeddable 2 NON persistable types have been enhanced: Main test.Manager
You can also specify the names of classes that can be located on the classpath by using the syntax of import statements (for example, test.X for a single class or test.pc.* for a package):
$ java com.objectdb.Enhancer test.X test.pc.*
Use the -pu option with the name of a persistence unit to enhance all the managed classes that are defined in that persistence unit:
$ java com.objectdb.Enhancer -pu my-pu
The -cp option can be used to specify an alternative classpath (the default is the classpath in which the Enhancer itself is running):
$ java com.objectdb.Enhancer -cp src test.X test.pc.*
By default, classes are enhanced in place, which overwrites the original class and JAR files. To keep the original files unchanged, use the -d option to redirect the output to a different directory:
$ java com.objectdb.Enhancer -s "*.class" -d enhanced
Maven and ANT enhancement
Enhancement can be integrated into the build process.
The following Maven configuration uses the exec-maven-plugin to integrate enhancement into the build process:
<build> ... <plugins> ... <plugin> ... <groupId>org.codehaus.mojo</groupId> <artifactId>exec-maven-plugin</artifactId> <version>1.6.0</version> <dependencies> <dependency> <groupId>com.objectdb</groupId> <artifactId>objectdb</artifactId> <version>2.8.0</version> <scope>compile</scope> </dependency> </dependencies> <executions> <execution> <phase>compile</phase> <goals> <goal>java</goal> </goals> </execution> </executions> <configuration> <mainClass>com.objectdb.Enhancer</mainClass> <!-- List of your packages --> <arguments> <argument>com.x.y.a.*</argument> <argument>com.x.y.b.*</argument> </arguments> </configuration> </plugin> ... </plugins> ... </build>
Complete ObjectDB Maven projects are available for download on the Tutorial pages:
Similarly, enhancement can be integrated into an ANT build script, as follows:
<java classname="com.objectdb.Enhancer" fork="true" classpath="c:\objectdb\bin\objectdb.jar"> <arg line="-s c:\my-project\classes\*"/> </java>
Enhancement API
The ObjectDB Enhancer can also be invoked from Java code:
com.objectdb.Enhancer.enhance("test.pc.*,test.X");
The same arguments that can be specified on the command line can also be passed to the enhance method as a single string delimited by commas or spaces. In addition, a class loader for loading classes for enhancement can be specified as a second argument:
com.objectdb.Enhancer.enhance( "test.pc.*,test.X", text.X.class.getClassLoader());
The enhancement API and invocation of the Enhancer from Java code is useful, for instance, in implementing custom enhancement ANT tasks.
Load time (Java agent) enhancement
Instead of enhancing classes during the build, you can enhance them when they are loaded into the JVM by running the application with objectdb.jar as a Java agent. For example, if objectdb.jar is in c:\objectdb\bin, the JVM can be started as follows:
$ java -javaagent:c:\objectdb\bin\objectdb.jar MyApplication
If the JVM runs with the ObjectDB Enhancer as a Java agent, each loaded class is checked and automatically enhanced in memory, if applicable. However, the Java agent enhancer only enhances classes that are marked as persistable by annotations (for example, @Entityjakarta.persistence.EntityDeclares that the annotated class is an entity. and @Embeddablejakarta.persistence.EmbeddableDeclares a type whose instances are stored as an intrinsic part of an owning entity, sharing the identity of the entity.). Therefore, when using this technique, persistent fields can only be accessed directly from annotated, persistable user classes.
Enhancement by a Java agent is easy to use and convenient during development. For production releases, however, integrating the enhancement into the build process is recommended.
To use load-time enhancement in web applications, the web server or application server must be run with the Java agent JVM argument.
Setting a Java agent enhancer in an IDE
In Eclipse, JVM arguments can be set globally in:
Window > Preferences > Java > Installed JREs > Edit > Default VM Arguments
Or for a specific run configuration in:
Run Configurations… > Arguments > VM arguments
In NetBeans, JVM arguments can be set in the project properties:
Right-click the project > Properties > Run > VM Options
Automatic Java agent enhancer
Unless configured otherwise, ObjectDB tries to load the Enhancer as a Java agent and enhance classes at load time, even if a Java agent is not specified explicitly.
This enhancement technique has limitations compared to the other techniques described above. First, it currently works only on Sun JDK 6 or later (and not on JRE 6, for example). Second, classes that are loaded into the JVM before ObjectDB is accessed cannot be enhanced, so careful code organization is essential for it to work.
Therefore, explicitly specifying a Java agent, as explained above, is always recommended.