Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Automatic Hibernate Transaction Management with Spring?

How far does the spring framework go with transaction handling? My reading of the book "Spring In Action" suggestions with its examples that you create DAO methods that don't worry about Session and Transaction management fairly simply by setting up a session factory and transaction template in XML and then wiring them into your DAO. SpringSource.org's documentation, on the other hand, suggests that need tons of XML and/or annotation to make this happen.

What is the truth here, what is the simplest way I can take code along the lines of

get session from sessionfactory
open transaction
preform database actions
commit transaction with error handling

and make it just

preform database actions

reducing the amount of boiler plate transactional code that I have across my methods to a minimum?

like image 633
James McMahon Avatar asked Apr 16 '09 21:04

James McMahon


People also ask

Does Spring provide Programaatic transaction management?

Spring provides two means of programmatic transaction management: Using the TransactionTemplate. Using a PlatformTransactionManager implementation directly.

How does @transactional work in Spring?

So when you annotate a method with @Transactional , Spring dynamically creates a proxy that implements the same interface(s) as the class you're annotating. And when clients make calls into your object, the calls are intercepted and the behaviors injected via the proxy mechanism.

What does @transactional do in hibernate?

Transactions means all or nothing. If there is an exception thrown somewhere in the method, changes are not persisted in the database. Something called rollback happens. If you don't specify @Transactional , each DB call will be in a different transaction.

Which annotation is used for transaction management in Spring?

tx:annotation-driven element is used to tell Spring context that we are using annotation based transaction management configuration. transaction-manager attribute is used to provide the transaction manager bean name. transaction-manager default value is transactionManager but I am still having it to avoid confusion.


1 Answers

There is some work you are supposed to do to be able to do just that but it's not much at all. Supposedly, you will use JPA with pick your own provider, e.g. Hibernate. Then you need to place persistence.xml that defines the persistence unit in the META-INF folder:

<?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" 
             xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd" 
             version="1.0">
    <persistence-unit name="YourDatabasePersistenceUnitName" transaction-type="RESOURCE_LOCAL"/>           
</persistence>

Next, define everything necessary for database connection in the Spring application context you use, at minimum it should contain these:

<bean id="propertyConfigurer"
        class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
        <property name="locations">
            <list>
                <value>/WEB-INF/jdbc.properties</value>     
        </property>
    </bean>

    <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" 
          destroy-method="close" scope="singleton">
        <property name="driverClassName" value="org.postgresql.Driver"/>
        <property name="url" value="${jdbc.url}"/>
        <property name="username" value="${jdbc.username}"/>
        <property name="password" value="${jdbc.password}"/>
    </bean>

    <bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
        <property name="persistenceUnitName" value="YourDatabasePersistenceUnitName"/>
        <property name="dataSource" ref="dataSource"/>
        <property name="jpaVendorAdapter">
            <bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
                <property name="database" value="POSTGRESQL" />
                <property name="databasePlatform" value="org.hibernate.dialect.PostgreSQLDialect"/>
                <property name="showSql" value="true"/>
                <property name="generateDdl" value="false"/>
            </bean>
        </property>     
    </bean>

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

<tx:annotation-driven transaction-manager="transactionManager" />

<bean class="org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor" />

 <bean class="org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor"/>

Some properties above may be changed or added depending on your needs. The example is for JPA with Hibernate and PostgreSQL database as you may have guessed.

Now you can simply define your data access methods like this:

@Repository
@Transactional
public class UserJpaDAO {

    protected EntityManager entityManager;

    @PersistenceContext
    public void setEntityManager(EntityManager entityManager) {
        this.entityManager = entityManager;
    }

    public void save(User theUser) {
        entityManager.persist(theUser);
    }

    public User update(User theUser) {
        return entityManager.merge(theUser);
    }
 }

where User is a JPA entity defined by your application. You may manager transactions at manager/controller layer that calls your DAOs - in fact I do it that way - but I placed it together here not to clutter example too much.

Nice references that you may want to go straight to instead of my examples is http://icoloma.blogspot.com/2006/11/jpa-and-spring-fucking-cooltm_26.html The top 3 links it references are worth going to as well.

like image 67
topchef Avatar answered Nov 09 '22 03:11

topchef