You are here: Advanced Features > Enhancement Tools > Required Depedencies

Transparent Persistence Enhancement Example

You can inject transparent persistence awareness in your persisted classes without modifying their original code. This is done by enhancing the class-files at build time.

Required jars

For transparent activation/persistence you need following dependencies at compile time. (see also the dependency overview)

Enhance Persistent Classes

The first step is to enhance the persisted classes. One possibility is to introduce an Annotation to mark your persisted classes.

By the way, their are alternative way to select the enhanced classes. See here.

@Retention(RetentionPolicy.RUNTIME)
@Documented
@Target(ElementType.TYPE)
public @interface TransparentPersisted {
}
TransparentPersisted.java: Annotation to mark persisted classes

This Annotationis then used to mark all persisted classes.

@TransparentPersisted
public  class Person {
Person.java: Mark your domain model with the annotations

The next step is to create a class filter which reports all classes which should be enhanced. There filter checks for the presence of the annotation.

public  final  class AnnotationFilter implements ClassFilter {

    public  boolean accept(Class<?> aClass) {
        if(null==aClass || aClass.equals(Object.class)){
            return  false;
        }
        return hasAnnotation(aClass)
                || accept(aClass.getSuperclass());
    }

    private  boolean hasAnnotation(Class<?> aClass) {
        // We compare by name, to be class-loader independent
        Annotation[] annotations = aClass.getAnnotations();
        for (Annotation annotation : annotations) {
            if(annotation.annotationType().getName()
                    .equals(TransparentPersisted.class.getName())){
                return  true;
            }
        }
        return  false;
    }

}
AnnotationFilter.java: Build a filter

Enhancing Classes Using Ant

This enhancement step injects the required bytecode into the domain classes to support transparent activation/persistence.

<target  name="enhance">
    <!-- Change these according to your project -->
    <property  name="target"  value="./target/classes/"/>
    <property  name="libraries"  value="./lib/"/>

    <path  id="project.classpath">
        <pathelement  path="${target}"/>
        <fileset  dir="${libraries}">
            <include  name="*.jar"/>
        </fileset>
    </path>

    <!-- We enhance with an additional Ant-run step. You can put this also in an extra file -->
    <typedef  resource="instrumentation-def.properties"
             classpathref="project.classpath"
             loaderRef="instrumentation.loader"/>

    <!-- We filter by our annotation -->
    <typedef  name="annotation-filter"
             classname="com.db4odoc.tp.enhancement.AnnotationFilter"
             classpathref="project.classpath"
             loaderRef="instrumentation.loader"/>

    <db4o-instrument  classTargetDir="${target}"
                  verbose="true">
        <classpath  refid="project.classpath"/>
        <sources  dir="${target}">
            <include  name="**/*.class"/>
        </sources>

        <transparent-activation-step>
            <annotation-filter/>
        </transparent-activation-step>
    </db4o-instrument>
</target>
enhance-with-annotation.xml: Ant target for enhancing your classes after building them

Configure Eclipse to Run Ant Target

You can configure Eclipse to run the Ant build with each compile step. Right click on your project and choose 'Properties'. Then switch to 'Builders' and add a new one. Choose the 'Ant Builder'. On the new window choose the build-file which contains the example-code. Switch to the 'Targets'-Tab. There choose the enhance-target for the 'Auto-Build'. Now the enhancer-task will be run by Eclipse automatically. The example project above is configured this way.

Enhancing Classes Using Maven

It's also possible to enhance with Maven by using the Ant plugin.

<plugin>
    <artifactId>maven-antrun-plugin</artifactId>
    <version>1.6</version>
    <dependencies>
        <!-- We need the db4o tooling for enhancing stuff -->
        <dependency>
            <groupId>com.db4o</groupId>
            <artifactId>db4o-tools-java5</artifactId>
            <version>8.1-SNAPSHOT</version>
        </dependency>
    </dependencies>
    <executions>
        <execution>
            <phase>compile</phase>
            <configuration>
                <target>
                    <!-- We enhance with an additional Ant-run step. You can put this also in an extra file -->
                    <typedef  resource="instrumentation-def.properties"
                             classpathref="maven.compile.classpath"/>

                    <!-- We filter by our annotation -->
                    <typedef  name="annotation-filter"
                             classname="com.db4odoc.tp.enhancement.AnnotationFilter"
                             classpathref="maven.compile.classpath"/>

                    <db4o-instrument  classTargetDir="target/classes"
                              verbose="true">
                        <classpath  refid="maven.compile.classpath"/>
                        <sources  dir="target/classes">
                            <include  name="**/*.class"/>
                        </sources>

                        <transparent-activation-step>
                            <annotation-filter/>
                        </transparent-activation-step>
                    </db4o-instrument>
                </target>
            </configuration>
            <goals>
                <goal>run</goal>
            </goals>
        </execution>
    </executions>

</plugin>
pom.xml: Enhance persisted classes during the build

Check Enhancement

You can check if the enhancement worked correctly by checking for the activation interface. Such a check should be part of your test-suite to ensure that everything works correctly.

if (!Activatable.class.isAssignableFrom(Person.class)) {
    throw  new AssertionError("Expect that the " + Person.class + " implements " + Activatable.class);
}
TransparentPersistence.java: Check for enhancement

Using Transparent Activation

Configure the transparent activation in order to use it.

final EmbeddedConfiguration configuration = Db4oEmbedded.newConfiguration();
configuration.common().add(new TransparentActivationSupport());
ObjectContainer container = Db4oEmbedded.openFile(configuration, DATABASE_FILE_NAME);
TransparentPersistence.java: Add transparent activation

After that transparent activation is working properly you can transverse along the object graph and don’t have to worry about not activated objects:

Person person = queryByName(container, "Joanna the 10");
Person beginOfDynasty = person.getMother();

// With transparent activation enabled, you can navigate deeply
// nested object graphs. db4o will ensure that the objects
// are loaded from the database.
while (null != beginOfDynasty.getMother()) {
    beginOfDynasty = beginOfDynasty.getMother();
}
System.out.println(beginOfDynasty.getName());
TransparentPersistence.java: Activation just works

Using Transparent Persistence

Transparent persistence not only manages the activation, but also manages updating the objects. Configure transparent persistence in order to use it:

final EmbeddedConfiguration configuration = Db4oEmbedded.newConfiguration();
configuration.common().add(new TransparentPersistenceSupport(new DeactivatingRollbackStrategy()));
ObjectContainer container = Db4oEmbedded.openFile(configuration, DATABASE_FILE_NAME);
TransparentPersistence.java: Add transparent persistence

After that updated objects are automatically stored every time you commit.

Person person = queryByName(container, "Joanna the 10");
Person mother = person.getMother();
mother.setName("New Name");
// Just commit the transaction. All modified objects are stored
container.commit();
TransparentPersistence.java: Just update and commit. Transparent persistence manages all updates