Red Hat Training

A Red Hat training course is available for Red Hat Fuse

2.6. Sample Configurations

2.6.1. JDBC Data Source

Overview

If you need to access a database, the JDBC data source provides a convenient, general-purpose mechanism for connecting to a database and making SQL based queries and updates. To group multiple updates into a single transaction, you can instantiate a Spring DataSourceTransactionManager and create a transaction scope using the transacted() DSL command.

Sample JDBC configuration

Example 2.2, “Data Source Transaction Manager Configuration” shows how to instantiate a JDBC transaction manager, of DataSourceTransactionManager type, which is required if you want to integrate a JDBC connection with Spring transactions. The JDBC transaction manager requires a reference to data source bean (created here with the ID, dataSource).

Example 2.2. Data Source Transaction Manager Configuration

<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="
       http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
       http://camel.apache.org/schema/spring http://camel.apache.org/schema/spring/camel-spring.xsd">
    ...
    <!-- spring transaction manager -->
    <bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource"/>
    </bean>

    <!-- datasource to the database -->
    <bean id="dataSource" class="org.springframework.jdbc.datasource.SimpleDriverDataSource">
        <property name="driverClass" value="org.hsqldb.jdbcDriver"/>
        <property name="url" value="jdbc:hsqldb:mem:camel"/>
        <property name="username" value="sa"/>
        <property name="password" value=""/>
    </bean>

</beans>

JDBC data source transaction manager bean

In Example 2.2, “Data Source Transaction Manager Configuration”, the txManager bean is a local JDBC transaction manager instance, of DataSourceTransactionManager type. There is just one property you need to provide to the JDBC transaction manager: a reference to a JDBC data source.

JDBC data source bean

In Example 2.2, “Data Source Transaction Manager Configuration”, the dataSource bean is an instance of a JDBC data source, of javax.sql.DataSource type. The JDBC data source is a standard feature of the Java DataBase Connectivity (JDBC) specification and it represents a single JDBC connection, which encapsulating the information required to connect to a specific database.
In Spring, the recommended way to create a data source is to instantiate a SimpleDriverDataSource bean (which implements the javax.sql.DataSource interface). The simple driver data source bean creates a new data source using a JDBC driver class (which is effectively a data source factory). The properties that you supply to the driver manager data source bean are specific to the database you want to connect to. In general, you need to supply the following properties:
driverClass
An instance of java.sql.Driver, which is the JDBC driver implemented by the database you want to connect to. Consult the third-party database documentation for the name of this driver class (some examples are given in Table 2.6, “Connection Details for Various Databases”).
url
The JDBC URL that is used to open a connection to the database. Consult the third-party database documentation for details of the URL format (some examples are given in Table 2.6, “Connection Details for Various Databases”).
For example, the URL provided to the dataSource bean in Example 2.2, “Data Source Transaction Manager Configuration” is in a format prescribed by the HSQLDB database. The URL, jdbc:hsqldb:mem:camel, can be parsed as follows:
  • The prefix, jdbc:hsqldb:, is common to all HSQLDB JDBC connection URLs;
  • The prefix, mem:, signifies an in-memory (non-persistent) database;
  • The final identifier, camel, is an arbitrary name that identifies the in-memory database instance.
username
The username that is used to log on to the database.
For example, when a new HSQLDB database instance is created, the sa user is created by default (with administrator privileges).
password
The password that matches the specified username.

Standalone data sources

Spring provides a variety of data source implementations, which are suitable for standalone mode (that is, the application is not deployed inside an OSGi container). These data sources are described in Table 2.3, “Standalone Data Source Classes”.

Table 2.3. Standalone Data Source Classes

Data Source ClassDescription
SimpleDriverDataSource
This data source should always be used in standalone mode. You configure this data source by providing it with details of a third-party JDBC driver class. This implementation has the following features:
  • Caches credentials for opening connections.
  • Supports multi-threading.
  • Compatible with the Spring transaction API.
  • Compatible with OSGi.
DriverManagerDataSource (Deprecated) Incompatible with OSGi containers. This class is superseded by the SimpleDriverDataSource.
SingleConnectionDataSource A data source that opens only one database connection (that is, every call to getConnection() returns a reference to the same connection instance). It follows that this data source is incompatible with multi-threading and is therefore not recommended for general use.

J2EE data source adapters

If your application is deployed into a J2EE container, it does not make sense to create a data source directly. Instead, you should let the J2EE container take care of creating data sources and you can then access those data sources by doing a JNDI lookup. For example, the following code fragment shows how you can obtain a data source from the JNDI reference, java:comp/env/jdbc/myds, and then wrap the data source with a UserCredentialsDataSourceAdapter.
 <bean id="myTargetDataSource" class="org.springframework.jndi.JndiObjectFactoryBean">
   <property name="jndiName" value="java:comp/env/jdbc/myds"/>
 </bean>

 <bean id="myDataSource" class="org.springframework.jdbc.datasource.UserCredentialsDataSourceAdapter">
   <property name="targetDataSource" ref="myTargetDataSource"/>
   <property name="username" value="myusername"/>
   <property name="password" value="mypassword"/>
 </bean>
The JndiObjectFactoryBean exploits the Spring bean factory pattern to look up an object in JNDI. When this bean's ID, myTargetDataSource, is referenced elsewhere in Spring using the ref attribute, instead of getting a reference to the JndiObjectFactoryBean bean, you actually get a reference to the bean that was looked up in JNDI (a javax.sql.DataSource instance).
The standard javax.sql.DataSource interface exposes two methods for creating connections: getConnection() and getConnection(String username, String password). If (as is normally the case) the referenced database requires credentials in order to open a connection, the UserCredentialsDataSourceAdapter class provides a convenient way of ensuring that these user credentials are available. You can use this adapter class for wrapping JNDI-provided data sources that do not have their own credentials cache.
In addition to UserCredentialsDataSourceAdapter, there are a number of other adapter classes that you can use to wrap data sources obtained from JNDI lookups. These J2EE data source adapters are summarized in Table 2.4, “J2EE Data Source Adapters”.

Table 2.4. J2EE Data Source Adapters

Data Source AdapterDescription
UserCredentialsDataSourceAdapter
Data source wrapper class that caches username/password credentials, for cases where the wrapped data source does not have its own credentials cache. This class can be used to wrap a data source obtained by JNDI lookup (typically, in a J2EE container).
The username/password credentials are bound to a specific thread. Hence, you can store different connection credentials for different threads.
IsolationLevelDataSourceAdapter Subclass of UserCredentialsDataSourceAdapter which, in addition to caching user credentials, also applies the current Spring transaction's level of isolation to all of the connections it creates.
WebSphereDataSourceAdapter Same functionality as IsolationLevelDataSourceAdapter, except that the implementation is customized to work with IBM-specific APIs.

Data source proxies for special features

You can wrap a data source with a data source proxy in order to add special functionality to a data source. The data source proxies can be applied either to a standalone data source or a data source provided by the container. They are summarized in Table 2.5, “Data Source Proxies”.

Table 2.5. Data Source Proxies

Data Source ProxyDescription
LazyConnectionDataSourceProxy
This proxy uses lazy semantics to avoid unnecessary database operations. That is, a connection will not actually be opened until the application code attempts to write (or read) to the database.
For example, if some application code opens a connection, begins a transaction, and then commits a transaction, but never actually accesses the database, the lazy connection proxy would optimize these database operations away.
TransactionAwareDataSourceProxy
Provides support for legacy database code that is not implemented using the Spring persistence API.
Do not use this proxy for normal transaction support. The other Spring data sources are already compatible with the Spring persistence and transaction APIs. For example, if your application code uses Spring's JdbcTemplate class to access JDBC resources, do not use this proxy class.

Third-party JDBC driver managers

Table 2.6, “Connection Details for Various Databases” shows the JDBC connection details for a variety of different database products.

Table 2.6. Connection Details for Various Databases

DatabaseJDBC Driver Manager Properties
HSQLDB
The JDBC driver class for HSQLDB is as follows:
org.hsqldb.jdbcDriver
To connect to a HSQLDB database, you can use one of the following JDBC URL formats:
jdbc:hsqldb:hsql[s]://host[:port][/DBName][KeyValuePairs]
jdbc:hsqldb:http[s]://host[:port][/DBName][KeyValuePairs]
jdbc:hsqldb:mem:DBName[KeyValuePairs]
Where the hsqls and https protocols use TLS security and the mem protocol references an in-process, transient database instance (useful for testing). For more details, see http://www.hsqldb.org/doc/src/.
MySQL
The JDBC driver class for MySQL is as follows:
com.mysql.jdbc.Driver
To connect to a MySQL database, use the following JDBC URL format:
jdbc:mysql://[host][,failoverhost...][:port]/[DBName][Options]
Where the Options coincidentally have the same format as Camel component options—for example, ?Option1=Value1&Option2=Value2. For more details, see http://dev.mysql.com/doc/connector-j/en/connector-j-reference-configuration-properties.html.
Oracle
Depending on which version of Oracle you are using choose one of the following JDBC driver classes:
oracle.jdbc.OracleDriver (Oracle 9i, 10)
oracle.jdbc.driver.OracleDriver (Oracle 8i)
To connect to an Oracle database, use the following JDBC URL format:
jdbc:oracle:thin:[user/password]@[host][:port]:SID
Where the Oracle System ID (SID) identifies an Oracle database instance. For more details, see http://download.oracle.com/docs/cd/B10501_01/java.920/a96654/basic.htm.
DB2
The JDBC driver class for DB2 is as follows:
com.ibm.db2.jcc.DB2Driver
To connect to a DB2 database, use the following JDBC URL format:
jdbc:db2://host[:port]/DBName
SQL Server
The JDBC driver class for SQL Server is as follows:
com.microsoft.jdbc.sqlserver.SQLServerDriver
To connect to a SQL Server database, use the following JDBC URL format:
jdbc:microsoft:sqlserver://host[:port];DatabaseName=DBName
Sybase
The JDBC driver class for Sybase is as follows:
com.sybase.jdbc3.jdbc.SybDriver
To connect to a Sybase database, use the following JDBC URL format:
jdbc:sybase:Tds:host:port/DBName
Informix
The JDBC driver class for Informix is as follows:
com.informix.jdbc.IfxDriver
To connect to an Informix database, use the following JDBC URL format:
jdbc:informix-sqli://host:port/DBName:informixserver=DBServerName
PostgreSQL
The JDBC driver class for PostgreSQL is as follows:
org.postgresql.Driver
To connect to a PostgreSQL database, use the following JDBC URL format:
jdbc:postgresql://host[:port]/DBName
MaxDB
The JDBC driver class for the SAP database is as follows:
com.sap.dbtech.jdbc.DriverSapDB
To connect to a MaxDB database, use the following JDBC URL format:
jdbc:sapdb://host[:port]/DBName
FrontBase
The JDBC driver class for FrontBase is as follows:
com.frontbase.jdbc.FBJDriver
To connect to a FrontBase database, use the following JDBC URL format:
jdbc:FrontBase://host[:port]/DBName

2.6.2. Hibernate

Overview

To enable transactions while accessing Hibernate objects, you need to provide an instance of the Hibernate transaction manager, of HibernateTransactionManager type, as described here. You can then use the transacted() DSL command to create a transaction scope in a route.

Sample Hibernate configuration

Example 2.3, “Hibernate Transaction Manager Configuration” shows how to instantiate a Hibernate transaction manager, of HibernateTransactionManager type, which is required if you want to integrate Hibernate object-oriented persistence with Spring transactions. The Hibernate transaction manager requires a reference to a Hibernate session factory, and the Hibernate session factory takes a reference to a JDBC data source.

Example 2.3. Hibernate Transaction Manager Configuration

<beans ... >
    ...
    <bean id="myDataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
        <property name="driverClassName" value="org.hsqldb.jdbcDriver"/>
        <property name="url" value="jdbc:hsqldb:hsql://localhost:9001"/>
        <property name="username" value="sa"/>
        <property name="password" value=""/>
    </bean>

    <bean id="mySessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
        <property name="dataSource" ref="myDataSource"/>
        <property name="mappingResources">
            <list>
                <value>product.hbm.xml</value>
            </list>
        </property>
        <property name="hibernateProperties">
            <value>
                hibernate.dialect=org.hibernate.dialect.HSQLDialect
            </value>
        </property>
    </bean>

    <bean id="hibernateTxManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
        <property name="sessionFactory" ref="mySessionFactory"/>
    </bean>
</beans>

Hibernate transaction manager bean

In Example 2.3, “Hibernate Transaction Manager Configuration”, the hibernateTxManager bean is a local Hibernate transaction manager instance, of HibernateTransactionManager type. There is just one property you need to provide to the Hibernate transaction manager: a reference to a Hibernate session factory.

Hibernate session factory bean

In Example 2.3, “Hibernate Transaction Manager Configuration”, the mySessionFactory bean is a Hibernate session factory of org.springframework.orm.hibernate3.LocalSessionFactory type. This session factory bean is needed by the Hibernate transaction manager.
In general, you need to supply the following properties to a Hibernate LocalSessionFactory bean instance:
dataSource
An instance of javax.sql.DataSource, which is the JDBC data source of the database that Hibernate is layered over. For details of how to configure a JDBC data source, see Section 2.6.1, “JDBC Data Source”.
mappingResources
Specifies a list of one or more mapping association files on the class path. A Hibernate mapping association defines how Java objects map to database tables.
hibernateProperties
Allows you to set any Hibernate property, by supplying a list of property settings. The most commonly needed property is hibernate.dialect, which indicates to Hibernate what sort of database it is layered over, enabling Hibernate to optimize its interaction with the underlying database. The dialect is specified as a class name, which can have one of the following values:
org.hibernate.dialect.Cache71Dialect
org.hibernate.dialect.DataDirectOracle9Dialect
org.hibernate.dialect.DB2390Dialect
org.hibernate.dialect.DB2400Dialect
org.hibernate.dialect.DB2Dialect
org.hibernate.dialect.DerbyDialect
org.hibernate.dialect.FirebirdDialect
org.hibernate.dialect.FrontBaseDialect
org.hibernate.dialect.H2Dialect
org.hibernate.dialect.HSQLDialect
org.hibernate.dialect.IngresDialect
org.hibernate.dialect.InterbaseDialect
org.hibernate.dialect.JDataStoreDialect
org.hibernate.dialect.MckoiDialect
org.hibernate.dialect.MimerSQLDialect
org.hibernate.dialect.MySQL5Dialect
org.hibernate.dialect.MySQL5InnoDBDialect
org.hibernate.dialect.MySQLDialect
org.hibernate.dialect.MySQLInnoDBDialect
org.hibernate.dialect.MySQLMyISAMDialect
org.hibernate.dialect.Oracle9Dialect
org.hibernate.dialect.OracleDialect
org.hibernate.dialect.PointbaseDialect
org.hibernate.dialect.PostgreSQLDialect
org.hibernate.dialect.ProgressDialect
org.hibernate.dialect.RDMSOS2200Dialect
org.hibernate.dialect.SAPDBDialect
org.hibernate.dialect.SQLServerDialect
org.hibernate.dialect.Sybase11Dialect
org.hibernate.dialect.SybaseAnywhereDialect
org.hibernate.dialect.SybaseDialect
org.hibernate.dialect.TimesTenDialect

2.6.3. JPA

Overview

To enable transactions in a JPA component, you need to provide the JPA component with a reference to a transaction manager, of JpaTransactionManager type. The Java Persistence API is a generic wrapper API for object-relational persistence and it can be layered over a variety of different object-relational mapping technologies.

Sample JPA configuration

Example 2.4, “JPA Transaction Manager Configuration” shows how to customize the configuration of a JPA component (creating a component with the bean ID, jpa), so that the JPA component supports Spring transactions. When used with transactions, the JPA component requires a reference to an entity manager factory and a reference to a transaction manager.

Example 2.4. JPA Transaction Manager Configuration

<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">

    <bean id="jpa" class="org.apache.camel.component.jpa.JpaComponent">
       <property name="entityManagerFactory" ref="entityManagerFactory"/>
       <property name="transactionManager" ref="jpaTxManager"/>
    </bean>

    <bean id="jpaTxManager" class="org.springframework.orm.jpa.JpaTransactionManager">
        <property name="entityManagerFactory" ref="entityManagerFactory"/>
    </bean>

    <bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalEntityManagerFactoryBean">
        <property name="persistenceUnitName" value="camel"/>
    </bean>

</beans>

JPA transaction manager bean

In Example 2.4, “JPA Transaction Manager Configuration”, the jpaTxManager bean is a local JPA transaction manager instance, of JpaTransactionManager type. The JPA transaction manager requires a reference to an entity manager factory bean (in this example, the entityManagerFactory bean).
If you deploy your application into an OSGi container, however, you might want to consider using a JtaTransactionManager instead. See Table 2.2, “Global Transaction Managers”.

Entity manager factory bean

The entity manager factory bean encapsulates the JPA runtime functionality. For example, the Spring LocalEntityManagerFactoryBean class is just a wrapper around the standard javax.persistence.EntityManagerFactory class. The entity manager factory is used to create a javax.persistence.EntityManager instance, where the entity manager is associated with a unique persistence context. A persistence context represents a consistent set of entity objects that are instantiated from the underlying database (analogous to a Hibernate session).
The LocalEntityManagerFactoryBean class is a relatively simple JPA wrapper class that is suitable for simple demonstrations and testing purposes. This class reads its required configuration information from the persistence.xml file, which is found at the standard location, META-INF/persistence.xml, on the class path (see ???). The persistenceUnitName property references a section of the persistence.xml file.

JPA entity manager factories

As well as instantiating a LocalEntityManagerFactoryBean bean, there are other ways of obtaining a JPA entity manager factory, as summarized in Table 2.7, “Obtaining JPA Entity Manager Factory”.

Table 2.7. Obtaining JPA Entity Manager Factory

Entity Manager FactoryDescription
Obtain from JNDI If your application is deployed in a J2EE container, the recommended approach is to let the container take care of instantiating the entity manager factory. You can then obtain a reference to the entity manager factory using JNDI. See Obtaining an EntityManagerFactory from JNDI in the Spring documentation.
LocalEntityManagerFactoryBean For simple standalone applications and for testing, the simplest option is to create a bean of this type. The JPA runtime is configured using the standard META-INF/persistence.xml file.
LocalContainerEntityManagerFactoryBean Use this class, if you need to configure special bootstrap options for the JPA runtime. In spite of the name, this class is not restricted to containers; you can also use it in standalone mode. See LocalContainerEntityManagerFactoryBean in the Spring documentation.

JPA bootstrap contract

The JPA is a thin abstraction layer that allows you to write code that is independent of a particular object-relational mapping product—for example, it enables you to layer your application over products such as OpenJPA, Hibernate, or TopLink. To match the application code to a specific JPA implementation, JPA defines a bootstrap contract, which is a procedure to locate and configure JPA implementations, as follows:
  • To make a JPA implementation available to your application, put the JAR file containing the relevant JPA provider class (of javax.persistence.spi.PersistenceProvider type) on your class path. In fact, it is possible to add multiple JPA providers to your class path: you can optionally specify which JPA provider to use in the persistence.xml file.
  • The JPA persistence layer is configured by the standard persistence.xml file, which is normally located in META-INF/persistence.xml on the class path.

Sample persistence.xml file

Example 2.5, “Sample persistence.xml File” shows a sample persistence.xml file for configuring an OpenJPA JPA provider layered over a Derby database.

Example 2.5. Sample persistence.xml File

<?xml version="1.0" encoding="UTF-8"?>
<persistence xmlns="http://java.sun.com/xml/ns/persistence"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             version="1.0"
             xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd">

  <persistence-unit name="camel" transaction-type="RESOURCE_LOCAL">
    <!--
        The default provider can be OpenJPA, or some other product.
        This element is optional if OpenJPA is the only JPA provider
        in the current classloading environment, but can be specified
        in cases where there are multiple JPA implementations available.
    -->
    <provider> 1
      org.apache.openjpa.persistence.PersistenceProviderImpl
    </provider>

    <class>org.apache.camel.examples.MultiSteps</class> 2
    <class>org.apache.camel.examples.SendEmail</class>

    <properties> 3
      <property name="openjpa.ConnectionURL" value="jdbc:derby:target/derby;create=true"/>
      <property name="openjpa.ConnectionDriverName" value="org.apache.derby.jdbc.EmbeddedDriver"/>
      <property name="openjpa.jdbc.SynchronizeMappings" value="buildSchema"/>
      <property name="openjpa.Log" value="DefaultLevel=WARN, Tool=INFO, SQL=TRACE"/>
    </properties>
  </persistence-unit>

</persistence>
1
The provider element can be used to specify the OpenJPA provider implementation class. If the provider element is omitted, the JPA layer simply uses the first JPA provider it can find. Hence, it is recommended to specify the provider element, if there are multiple JPA providers on your class path.
To make a JPA provider available to an application, simply add the provider's JAR file to the class path and the JPA layer will auto-detect the JPA provider.
2
Use the class elements to list all of the Java types that you want to persist using the JPA framework.
3
Use the properties element to configure the underlying JPA provider. In particular, you should at least provide enough information here to configure the connection to the underlying database.

Sample annotated class

The following code example shows how the org.apache.camel.examples.SendEmail class referenced in Example 2.5, “Sample persistence.xml File” should be annotated to turn it into a persistent entity bean (so that it is persistible by JPA):
// Java
package org.apache.camel.examples;

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;

/**
 * Represents a task which is added to the database, then removed from the database when it is consumed
 *
 * @version $Revision$
 */
@Entity
public class SendEmail {
    private Long id;
    private String address;

    public SendEmail() {
    }

    public SendEmail(String address) {
        setAddress(address);
    }

    @Override
    public String toString() {
        return "SendEmail[id: " + getId() + " address: " + getAddress() + "]";
    }

    @Id
    @GeneratedValue
    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getAddress() {
        return address;
    }

    public void setAddress(String address) {
        this.address = address;
    }
}
The preceding class has the following JPA annotations:
@javax.persistence.Entity
Specifies that the following class is persistible by the JPA.
@javax.persistence.Id
The following bean property must be used as the primary key (for locating objects of this type in the database).
@javax.persistence.GeneratedValue
Specifies that the primary key values should be automatically generated by the JPA runtime (you can optionally set attributes on this annotation to configure the ID generation algorithm as well).
For the complete list of JPA annotations, see the API for the javax.persistence package.