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
- Spring configured data sources
- A Spring transaction manager (in contrast to Atomikos as in Sample-jta-spring or the built-in TM as in Sample-spring-hibernate).
This is another practical application of How to Spring.
This sample is stored in z2-samples.springds-hibernate.
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 - 2.5||Java 8||Java 8|
|2.6 - master||Java 9||Java 9|
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
(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¶
Previously to Java 9, the Java SE Development Kit (JDK) by Oracle provided the Java DB - essentially the same as the Apache Derby DB. That is not the case anymore. However, we use that Database implementation in our samples. In order to run those samples that illustrate use of a relational database, please follow the instructions below to install and run Apache Derby. Could hardly be simpler.
Step 1: Download and Install¶
Note: You do not need to unpack Apache Derby into some global folder on your system. Instead you may want to use some local folder under your user's home folder. There is no problem installing and runnning different instances and configurations at any time.
Step 2: Run¶
Let's assume you installed (well - unpacked) into a folder $DERBY_INSTALL. Also, let's assume some Java Runtime Environment is installed and ready.
Simply run the following on Linux or Mac OS:
cd $DERBY_INSTALL java -jar lib/derbyrun.jar server start
On Windows run
cd %DERBY_INSTALL java -jar lib\derbyrun.jar server start
That's it. Apache Derby will be waiting for connections on port 1527.
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 v2.5 http://git.z2-environment.net/z2-base.core git clone -b v2.5 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:
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>