A sample using Vaadin with Hibernate JPA and Spring on Z2

This sample is similar to Sample-spring-hibernate but differs (or rather extends) in that it show cases
the use of the Vaadin user interface toolkit in conjunction with Spring implemented annotation based
dependency injection over Z2 modularity.

As Spring is used throughout - in all modules - this is another practical application of How to Spring.

Moreover this sample illustrates modularization of Vaadin user interfaces with Z2 using extension points as described in Vaadin add-on.

This sample is stored in z2-samples.vaadin-spring-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.vaadin-spring-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/vaadin-spring-hibernate. You should see this:

Details

As in the other samples we have a re-use domain module. That is a recurring theme for many good reasons. In this case, the domain module com.zfabrik.samples.vaadin-spring-hibernate.domain is essentially like the similarly named module of Sample-spring-hibernate. The only difference is some more data access methods in the ThingyRepository.

The Vaadin Web application is defined in the module com.zfabrik.samples.vaadin-spring-hibernate.web. It has the usual Spring application context in web/WebContent/WEB-INF/applicationContext.xml that imports the thingy repository:

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

One particularity of using Vaadin in a modular environment is that Vaadin loads it's application class using the class loader that loaded the Vaadin classes (rather than the current thread's context class loader - as would be advised normally). When the Web application module is separated from the Vaadin module this can obviously not work too well (see also Enhancement #9809). To fix that you can tell Vaadin to use a custom class loader implementation (that - again - is loaded with the Vaadin class loader). That's why we declare the Vaadin servlet in web/WebContent/WEB-INF/web.xml list this:

<!-- Vaadin -->
<servlet>
  <servlet-name>VaadinServlet</servlet-name>
  <servlet-class>com.vaadin.terminal.gwt.server.ApplicationServlet</servlet-class>
  <init-param>
    <param-name>application</param-name>
    <param-value>com.zfabrik.samples.impl.vaadin_spring_hibernate.ApplicationImpl</param-value>
  </init-param>
  <!-- this because Vaadin doesn't use the thread's context class loader by default -->
  <init-param>
    <param-name>ClassLoader</param-name>
    <param-value>com.zfabrik.vaadin.ContextClassLoader</param-value>
  </init-param>*
</servlet>

The Vaadin application class ApplicationImpl constructs a simple view hierarchy that containes a table view based on a lazy query container add-on data model that is fed from the domain module. To do so the corresponding query implementation (in lazy query container speak) has the repository injected:

@Configurable
public class ThingiesQuery implements Query {
    @Autowired
    private ThingyRepository repository;
    private Integer size;
    private boolean asc;

// ...
}

Please browse the actual UI code at com.zfabrik.samples.vaadin-spring-hibernate.web/java/src.impl/com/zfabrik/samples/impl/vaadin_spring_hibernate. It pretty much speaks for itself.

Transaction Management

One important note on transaction management: In this example, transaction boundaries are enforced by a servlet filter once more. It is implemented in TransactionFilter and essentially looks like this:

public class TransactionFilter implements Filter {

        @Transactional
        @Override
        public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
                chain.doFilter(request, response);
        }

}

In other words, the only thing it really does is to make sure Spring spans a transaction (using the underlying JTA implementation) along the request. It is tempting to implement transaction demarcation in the Vaadin Application class. However, we cannot use the @Transactional annotation as there is no single request spanning method and using the JTA UserTransaction object is unfortunately not sufficient to "remote control" Spring's JTA wrappers. So the easiest work around is to use Spring TX demarcation right away (see also how to transaction management).

Extensibility

Furthermore this sample illustrates the use of the ExtensionComponentsUtil (javadoc) as described in detail at Vaadin_Add-on. This utility allows to conveniently modularize the user interface implementation by providing and retrieving Vaadin user interface component implementations across modules.

In the specific case, the module com.zfabrik.samples.vaadin-spring-hibernate.extension provides an extension component somethingAboutThingies that is added as the button "About these..." to the button toolbar of the main interface.

The component declaration makes sure the implementation can be found and (important!) that the module's Spring application context is loaded before providing the component implementation

#
# A Vaadin UI extension 
#
com.zfabrik.component.type=com.vaadin.ui.Component

#
# Coordinates:
#
com.zfabrik.vaadin.extension.point=com.zfabrik.samples.vaadin_spring_hibernate.actions
com.zfabrik.vaadin.extension.order=100

#
# The implementation class
#
component.className=com.zfabrik.samples.impl.vaadin_spring_hibernate.ext.SomethingAboutThingies

#
# make sure the app context is loaded first
#
com.zfabrik.component.dependencies=\
     com.zfabrik.samples.vaadin-spring-hibernate.extension/applicationContext

The user interface that assembles consumes this extension is at ThingiesView and adds extensions like this:

// find extensions and add them to the button row
for (Component c : ExtensionComponentsUtil.getComponentyByExtensionForApplication(application,"com.zfabrik.samples.vaadin_spring_hibernate.actions")) {
    // and add them to this.
    buttons.addComponent(c);
}

vaadin-spring-hibernate.png (49.5 KB) Henning Blohm, 07.07.2013 14:14