Get ahead
VMware offers training and certification to turbo-charge your progress.
Learn moreThis is the third part in a series of blog posts highlighting some of the new features available in Spring Integration 2.2 following the recent release of Release Candidate 1. The first part described the new set of MongoDB adapters. In part two we highlighted the new extended support for synchronizing non-transactional resources with transactions.
In this third part today, we would like to introduce the new Java Persistence API (JPA) support that is provided starting with Spring Integration 2.2. The JPA module is persistence-provider-agnostic and has been tested using:
As part of the new JPA module, we provide several components for retrieving and persisting JPA entity objects:The provided sample is using an embedded H2 database which contains a single table called PEOPLE. This table is mapped to the Person entity class in package org.springframework.integration.samples.jpa. With that setup we cover two simple use-cases:
$ git clone https://github.com/SpringSource/spring-integration-samples.git
Next, go to the JPA sample directory:
$ cd spring-integration-samples/basic/jpa
Now we can build and run the application by executing the following Maven command:
$ mvn clean package exec:exec
Eventually the application starts up and you should see the following screen:
=========================================================
Welcome to the Spring Integration JPA Sample!
For more information please visit:
http://www.springintegration.org/
=========================================================
Please enter a choice and press enter:
1. Use Hibernate
2. Use OpenJPA
3. Use EclipseLink
q. Quit the application
Enter you choice:
The JPA sample allows you to execute the JPA operations using one of the following persistance providers: Hibernate, OpenJPA or EclipseLink. At application startup you will therefore be able to choose the desired persistence provider. Once selected, you can select which specific JPA operation to execute:
Please enter a choice and press enter:
1. List all people
2. Create a new person
q. Quit the application
Enter you choice:
You can either list each Person from the PEOPLE table (Option 1):
Enter you choice: 1
ID NAME CREATED
==================================
1001, Cartman, 2012-10-04 16:14:02
==================================
or you can create a new Person (Option 2):
Enter the Person's name:Demo User
Created person record with id: 1002
Do you want to create another person? (y/n)
...
/src/main/resources/META-INF/spring/integration/commonJpa-context.xml
This file does not contain anything Spring Integration specific. All we do, is to setup the embedded database, the respective DataSource, the EntityManagerFactory and the Transaction Manager.
The JPA persistence provider specific configuration is located under:
/src/main/resources/META-INF/spring/integration/eclipselink-context.xml
/src/main/resources/META-INF/spring/integration/hibernate-context.xml
/src/main/resources/META-INF/spring/integration/openjpa-context.xml
As you will see, these configurations are very light-weight, containing only the persistence provider specific JpaVendorAdapter bean declarations.
Everything Spring Integration specific is configured in:
/src/main/resources/META-INF/spring/integration/spring-integration-context.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:int="http://www.springframework.org/schema/integration"
xmlns:int-jpa="http://www.springframework.org/schema/integration/jpa"
xmlns:jdbc="http://www.springframework.org/schema/jdbc"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc.xsd
http://www.springframework.org/schema/integration http://www.springframework.org/schema/integration/spring-integration.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd
http://www.springframework.org/schema/integration/jpa http://www.springframework.org/schema/integration/jpa/spring-integration-jpa.xsd">
<int:channel id="createPersonRequestChannel"/>
<int:channel id="listPeopleRequestChannel"/>
<int:gateway id="personService"
service-interface="org.springframework.integration.samples.jpa.service.PersonService"
default-request-timeout="5000" default-reply-timeout="5000">
<int:method name="createPerson" request-channel="createPersonRequestChannel"/>
<int:method name="findPeople" request-channel="listPeopleRequestChannel"/>
</int:gateway>
<int-jpa:retrieving-outbound-gateway entity-manager-factory="entityManagerFactory"
request-channel="listPeopleRequestChannel"
jpa-query="select p from Person p order by p.name asc">
</int-jpa:retrieving-outbound-gateway>
<int-jpa:updating-outbound-gateway entity-manager-factory="entityManagerFactory"
request-channel="createPersonRequestChannel" >
<int-jpa:transactional transaction-manager="transactionManager" />
</int-jpa:updating-outbound-gateway>
<!-- Depending on the selected profile, users can use different JPA Providers -->
<beans profile="default, hibernate">
<import resource="classpath:/META-INF/spring/integration/hibernate-context.xml"/>
</beans>
<beans profile="openjpa">
<import resource="classpath:/META-INF/spring/integration/openjpa-context.xml"/>
</beans>
<beans profile="eclipselink">
<import resource="classpath:/META-INF/spring/integration/eclipselink-context.xml"/>
</beans>
</beans>
Both, the Retrieving Outbound Gateway and the Updating Outbound Gateway are wired up with an EntityManagerFactory reference. Alternatively, we also provide means to pass-in a reference to an EntityManager directly.
The Retrieving Outbound Gateway is also configured with an JPQL query to retrieve all people from the database ordered by their name. The Updating Outbound Gateway on the other hand does not specify any queries at all. It directly uses the Person object that is being passed in as the Spring Integration Message payload. Ultimately, the Person object is passed to the EntityManager and persisted to the database. Furthermore, the Updating Outbound Gateway is being declared transactional ensuring that the JPA session is flushed and the data committed to the database.
<int-jpa:parameter/>
sub-element. For example, you can provide Named Parameters by specifying:
<int-jpa:parameter name="myNamedParam" type="java.lang.String" value="myParamValue"/>
Alternatively, you can also provide Positional Parameters by leaving off the name attribute:
<int-jpa:parameter type="java.lang.String" value="myFirstParam"/>
<int-jpa:parameter type="java.lang.Integer" value="2"/>
Lastly, if you are using the Outbound Channel Adapter or any of the Outbound Gateways, you can also provide dynamic parameters using the Spring Expression Language (SpEL), giving you easy access to values from the Message's payload or its Message headers:
<int-jpa:parameter expression="payload.name" name="firstName"/>