A sample using Spring data sources and Spring transaction management in a modular application

This sample is very similar to Sample-spring-hibernate but differs in that we use

This is another practical application of How to Spring.

This sample is stored in z2-samples.springds-hibernate.

Prerequisites

Z2 has the following Java Version requirements

Z2 Version Min. Java version required Max Java version supported
2.1 - 2.3.1 Java 6 Java 7
2.4 - master Java 8 Java 8

Note: Most samples suggest to use the master branch. You may choose another version branch (please check the respective repository).
Make sure you have a corresponding Java Development Kit (JDK) or Java Runtime Environment (JRE) installed. If in doubt, go to Download Java SE.

Note: Running v2.1-v2.3.1 on Java 8 is supported by specifying

com.zfabrik.java.level=7

(or 6, if that is your desired compilation language level) in <home>/run/bin/runtime.properties. By this the Java compiler version detection does not fall back to a lower level.

You need to run Java DB as network server on localhost. This is explained next.

The application will create a database "z2-samples"

Running a Java DB Network Server

In samples we use the Java DB, i.e. the SQL database implementation that comes with the Java SE Development Kit (JDK) by Oracle (except for Mac OS in which case you have to use Apache Derby). Java DB is the same as the Apache Derby DB - see also the installation how-to.

The instructions below apply to both, there is only a difference in the installation path.

For general information on Java DB go to http://docs.oracle.com/javadb/10.8.2.2/getstart/index.html

To run the Java DB in server mode, which is what we want to do, run

mkdir derby
cd derby
java -jar $JAVA_HOME/db/lib/derbyrun.jar server start

assuming you want to run it in the folder derby. At a second time you can omit the "mkdir" command of course. The environment variable JAVA_HOME is expected to point to your JDK installation folder. When you installed Apache Derby and followed the instructions mentioned above, you have to replace $JAVA_HOME by $DERBY_HOME.

On Windows run

mkdir derby
cd derby
java -jar "%JAVA_HOME%\db\lib\derbyrun.jar" server start

In order to interactively query Java DB, we recommend to use the Data Source Explorer view in Eclipse. But any SQL client that can make use of JDBC drivers should be fine. The driver for Java DB can be found (at the time of this writing) in $JAVA_HOME/db/lib/derbyclient.jar (and similarly on Windows).

Note: If you have problems running Derby due to Security Exceptions, it may be necessary to update your security profile as described in http://stackoverflow.com/questions/21154400/unable-to-start-derby-database-from-netbeans-7-4 (and please make sure you have a good JAVA_HOME and PATH setting).

Alternative: Using the DB-Worker Node Add-on (no separate RDBMS installation required)

you can also use the DB Worker Node Add-on which runs Apache Derby RDBM as a regular z2 worker process, so you don't need to install any extra database software.

How to augment the samples to use the DB Worker node?

You have to add the DB Worker Node Add-on to your samples environment and tell the server to start the DB worker node beside the web worker.
For this you can use the two files attached to this page:

  • dbWorkerAddon.properties - points to the z2 component repository containing the DB Worker Node Add-on
  • home.properties - a slightly changed home layout that launches the DB worker in addition to the web worker

Just download these two files and put them under .../install/z2-samples.XYZ/environment/ - where z2.samples.XYZ must be replaced by the concrete sample name like z2-samples.spring-hibernate

Run it

Like all samples, also this sample can be run as in How to run a sample. If you have the database, the fastest way to verify whether it runs is:

mkdir install
cd install 
git clone -b master http://git.z2-environment.net/z2-base.core
git clone -b master http://git.z2-environment.net/z2-samples.springds-hibernate

# on Linux / Mac OS:
cd z2-base.core/run/bin
./gui.sh

# on Windows:
cd z2-base.core\run\bin
gui.bat

When running, go to http://localhost:8080/springds-hibernate. You should see this:

Details

Similar to Sample-spring-hibernate, the assumption of this example is that of a re-use domain module com.zfabrik.samples.springds-hibernate.domain that implements a "Thingy Repository" and is used from a web application that is in another module com.zfabrik.samples.springds-hibernate.web.
The domain module declares the date source used as well as the transaction manager. The transaction manager is exposed as Z2 component.

The body of the application context (here) of the domain module looks like this:

    <!-- annotation based config -->
    <context:component-scan base-package="com.zfabrik.samples.spring_hibernate" />
    <context:annotation-config />

    <!-- DB config (no pooling here - but can be changed easily) -->
    <!--  Do not use DriverManagerDataSource here for class loading considerations -->

    <bean id="dataSource" class="org.apache.derby.jdbc.ClientDataSource">
        <property name="databaseName" value="z2-samples"/>
        <property name="serverName" value="localhost"/>
        <property name="portNumber" value="1527"/>
        <property name="createDatabase" value="create"/>
    </bean>

    <!-- The actual EMF we use -->
    <bean id="entityManagerFactory"    class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
        <property name="dataSource" ref="dataSource" />
        <property name="persistenceUnitName" value="thingies" />
        <property name="jpaVendorAdapter">
            <bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
                <property name="showSql" value="true" />
                <property name="generateDdl" value="true" />
                <property name="databasePlatform" value="org.hibernate.dialect.DerbyDialect" />
            </bean>
        </property>
    </bean>

    <!--  the transaction manager -->
    <bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
       <property name="entityManagerFactory" ref="entityManagerFactory" />
    </bean>

    <!-- EntityManager injection -->
    <bean class="org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor" />

The persistence unit "thingies", defined in the same module (as in java/src.impl/META-INF/applicationContext.xml), is essentially empty must be thought as completed by the application context declaration above (which is a Spring feature).

The domain module exposes the Thingy Repository as a Z2 component - from a Spring application context defined bean - that is imported into the application context of the Web application and injected into the controller filter by Spring.

The controller filter uses declarative transaction demarcation relying on the transaction manager exposed by the domain module (note the "transactionManager" bean declaration below).

Here is the body of the Web apps application context (as declared in WEB-INF/applicationContext.xml)

    <!-- Annotation Support -->
    <context:component-scan base-package="com.zfabrik.samples.spring_hibernate" />
    <context:spring-configured />
    <context:annotation-config />        

    <!-- import transaction manager from domain.   -->
    <bean id="transactionManager" class="com.zfabrik.springframework.ComponentFactoryBean">
        <property name="componentName"  value="com.zfabrik.samples.springds-hibernate.domain/transactionManager" />
        <property name="className"  value="org.springframework.transaction.support.AbstractPlatformTransactionManager" />
    </bean>

    <!-- make sure we can use @Transactional with the Spring aspect -->
    <tx:annotation-driven transaction-manager="transactionManager" mode="aspectj"/>

    <!-- import external services -->
    <bean id="thingyRepository" class="com.zfabrik.springframework.ComponentFactoryBean">
        <property name="componentName"  value="com.zfabrik.samples.springds-hibernate.domain/repository" />
        <property name="className"  value="com.zfabrik.samples.spring_hibernate.thingies.ThingyRepository" />
    </bean>

springds-hibernate.png (43.1 KB) Henning Blohm, 03.05.2014 18:39