Spring JPA web applications (JTA transactions, JBoss 5)

Submitted by Kamal Wickramanayake on June 13, 2010 - 07:32

With Spring 3.x, you can develop JPA applications very easily. Here you find guidelines in creating such an application with the following features:

  1. Use JTA for transaction management (with very little modifications you can use resource local transactions as well).
  2. Make sure the same JPA EntityManager instance is used across multiple DAOs so that a single business method can use multiple DAO method calls within the same transactional context.
  3. Make sure the same EntityManager instance is available for multiple DAOs in a thread safe manner.

Environment used is given below. You may use other versions of software with minor changes (for example Spring 3.0.1 and so on).

  1. Spring 3.0.0
  2. JBoss 5.1.0 (JDK 1.6 version)
  3. JDK
  4. Hibernate (the one packaged with JBoss 5.1.0)
  5. Database used: MySQL 5.1.37
  6. Development environment: Eclipse Galileo

Here are the steps:

1. Define the Spring configuration file in the web.xml file

        <description>Spring configuration file</description>

2. Define the Spring loader in the web.xml file

        <description>Spring Loader</description>

3. Define the persistence unit reference in the web.xml file:

            Persistence unit for the bank application.

4. Here's the persistence.xml file. Make the changes to the <jta-data-source> as you have defined in your system (for example in a file like JBOSS_HOME/server/default/deploy/bank-ds.xml - See JBOSS_HOME/docs/examples/jca/ for templates).

<?xml version="1.0" encoding="UTF-8"?>
<persistence version="1.0" xmlns="http://java.sun.com/xml/ns/persistence" 
  <persistence-unit name="BankAppPU" transaction-type="JTA">
      <!-- Auto-detect entity classes -->
      <property name="hibernate.archive.autodetection" value="class, hbm"/>

      <!-- Print sql executed - useful for debugging -->
      <property name="hibernate.show_sql" value="true"/>
      <property name="hibernate.format_sql" value="true"/>

      <property name="hibernate.transaction.manager_lookup_class" 
      <property name="hibernate.dialect" value="org.hibernate.dialect.MySQLDialect"/>

      <property name="hibernate.hbm2ddl.auto" value="create"/>

5. Here's a sample Spring configuration file (applicationContext.xml):

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"

    <!-- JPAAccountDAO has JPA annotations to access EntityManager -->

    <!-- Access the EntityManagerFactory like this - if ever you need -->
    <jee:jndi-lookup id="emf" jndi-name="persistence/BankAppPU"/>

    <!-- Here's a DAO that we will be using -->
    <bean id="accountDAO" class="bank.dao.jpa.JPAAccountDAO"/>

    <!-- Will be using the DAO in a business logic class AccountManager -->
    <bean id="accountManager" class="bank.AccountManagerImpl">
        <property name="accountDAO" ref="accountDAO"></property>

    <!-- Configure Transaction Support - Access the JTA transaction manager -->
    <bean id="txManager" class="org.springframework.transaction.jta.JtaTransactionManager">
          <property name="transactionManagerName" value="java:/TransactionManager"/>
        <property name="userTransactionName" value="UserTransaction"/>

    <!-- Use Spring AOP capabilities to manage transactions -->
      <aop:pointcut id="accountTransactions" 
               expression="execution(* bank.AccountManager.*(..))"/>
      <aop:advisor pointcut-ref="accountTransactions" advice-ref="txAdvice" />

    <tx:advice id="txAdvice" transaction-manager="txManager">
        <tx:method name="create" propagation="REQUIRED"/>
        <tx:method name="withdraw*" propagation="REQUIRED"/>
        <tx:method name="deposit*" propagation="REQUIRED"/>
        <tx:method name="chargeForLowBalance*" propagation="REQUIRED"/>
        <tx:method name="*" propagation="SUPPORTS" read-only="true"/>

6. Here's the sample AccountManagerImpl:

package bank;

import java.util.Iterator;
import java.util.List;

import bank.dao.AccountDAO;

public class AccountManagerImpl implements AccountManager {

    private AccountDAO accountDAO;
    public AccountDAO getAccountDAO() {
        return accountDAO;
    public void setAccountDAO(AccountDAO accountDAO) {
        this.accountDAO = accountDAO;

    public void chargeForLowBalance(double minimumBalance, double amount) {
        List<Account> accounts = accountDAO.findAccountsWithLowBalance(minimumBalance);
        for (Iterator<Account> iterator = accounts.iterator(); iterator.hasNext();) {
            Account account = (Account) iterator.next();
            // Check if the balance will go beyond 0. If yes, set the balance to 0
            account.setBalance(account.getBalance() - amount);

    public Account create() {
        return accountDAO.createAccount();

    public void delete(int accountNumber) {

    public void deposit(Account account, double amount) {
        //Account a = accountDAO.getAccount(accountNumber);
        account.setBalance(account.getBalance() + amount);

    public void deposit(int accountNumber, double amount) {
        Account account = accountDAO.getAccount(accountNumber);
        deposit(account, amount);

    public void withdraw(int accountNumber, double amount) {
        Account account = accountDAO.getAccount(accountNumber);
        withdraw(account, amount);
    public void withdraw(Account account, double amount) {
        if (account.getBalance() >= amount) {
            account.setBalance(account.getBalance() - amount);
        // Throw an exception (InsufficientBalanceException)?

7.  Here's the JPAAccountDAO class:

package bank.dao.jpa;

import java.util.List;

import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;

import bank.Account;
import bank.dao.AccountDAO;

public class JPAAccountDAO implements AccountDAO {

    private EntityManager em;

    public Account createAccount() {
        Account a = new Account();
        return a;

    public void delete(int accountNumber) {
        em.remove(em.find(Account.class, accountNumber));

    public List<Account> findAccountsWithLowBalance(double lessThanAmount) {
        return em.createQuery("select a from Account a where a.balance < :amount")
                .setParameter("amount", lessThanAmount).getResultList();

    public List<Account> findAllAccounts() {
        return em.createQuery("select a from Account a").getResultList();

    public Account getAccount(int accountNumber) {
        return em.find(Account.class, accountNumber);

    public void update(Account account) {


Note that I haven't gone into placing all the classes and interfaces I used in my demo app. Purpose of the above is for you to see the critical configurations that are needed.

Here's the summary:

  1. A data source is configured in the application server.
  2. A persistence unit is configured (with JTA transaction management).
  3. Spring configuration file is written to process annotations in classes.
  4. The DAO depends on PersistenceContext annotation to access an EntityManager.
  5. Spring is configured to use the JTA transaction manager (of the application server).

You can follow the same style in writing all the DAOs you need. Even though EntityManager instances are not thread safe (but EntityManagerFactory instances are) in general, here you find Spring injecting a an EntityManager instance which is thread safe. In fact, this EntityManager injected is not a real EntityManager instance, but a proxy implementing the same (EntityManager) interface.

When a method (like withdraw) in the AccountManager (business logic) is invoked, we have configured Spring to start a transaction. When a method of DAO is invoked within this transactional context, the proxy EntityManager in DAO receives the method call and goes into searching for a real EntityManager instance associated with the transactional context. If found, that EntityManager instance is used. If not found, the proxy EntityManager will go about creating a new "real" EntityManager instance and associate it with the current transaction. This makes the same "real" EntityManager instance available in multiple DAOs within the same transactional context.

Given that a transaction is associated with a thread, the above configuration also makes sure that the "real" EntityManager instances are correctly used in a thread-safe manner in a multi-threaded environment. That is, a certain "real" EntityManager instance created while processing a request is used only within that thread.

The created "real" EntityManager instances are closed automatically when the transactions are committed or rolled back. Spring automatically does this.