Автоматическое управление транзакциями Hibernate с помощью Spring? - PullRequest
11 голосов
/ 17 апреля 2009

Как далеко заходит среда Spring для обработки транзакций? Мое чтение книги «Spring In Action» предлагает на примерах с примерами, что вы создаете методы DAO, которые не беспокоятся об управлении сессиями и транзакциями, просто устанавливая фабрику сессий и шаблон транзакции в XML, а затем подключая их к вашему DAO. Документация SpringSource.org, с другой стороны, предполагает, что для этого нужно тонны XML и / или аннотаций.

В чем здесь правда, как проще всего взять код в духе

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

и сделай это просто

preform database actions

Сократить количество кода транзакции котельной пластины, которое у меня есть в моих методах, до минимума?

Ответы [ 2 ]

11 голосов
/ 17 апреля 2009

Есть некоторая работа, которую вы должны сделать, чтобы иметь возможность сделать это, но это совсем немного. Предположительно, вы будете использовать JPA с выбором собственного провайдера, например, Hibernate. Затем вам нужно поместить файл persistence.xml, который определяет единицу сохранения, в папку META-INF:

<?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>

Затем определите все необходимое для подключения к базе данных в используемом вами контексте приложения Spring, как минимум оно должно содержать:

<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"/>

Некоторые свойства выше могут быть изменены или добавлены в зависимости от ваших потребностей. Пример для JPA с базой данных Hibernate и PostgreSQL, как вы уже догадались.

Теперь вы можете просто определить свои методы доступа к данным следующим образом:

@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);
    }
 }

где Пользователь - это объект JPA, определенный вашим приложением. Вы можете управлять транзакциями на уровне диспетчера / контроллера, который вызывает ваши DAO - на самом деле я делаю это таким образом - но я собрал их здесь, чтобы не слишком загромождать пример.

Хорошие ссылки, к которым вы можете перейти прямо вместо моих примеров, http://icoloma.blogspot.com/2006/11/jpa-and-spring-fucking-cooltm_26.html 3 лучших ссылки, на которые он ссылается, тоже заслуживают внимания.

10 голосов
/ 17 апреля 2009

Spring предоставляет как минимум 3 способа разграничения транзакций:

1) Программная обработка через TransactionTemplate или PlatformTransactionManager - облегчает настройку, но инвазивна

2) Декларативный с помощью XML - подробный XML, но неинвазивный

3) Декларативный с помощью аннотаций - легкий XML, не инвазивный

Выбор того, что вы выберете, зависит от того, какой из них лучше всего соответствует вашим потребностям, Spring не сделает этот выбор за вас. От твоего вопроса звучит так, будто тебе нужен подход с аннотациями.

Я предлагаю прочитать справочное руководство Spring, раздел обработки транзакций на основе аннотаций. Это ясно и кратко.

Я всегда сначала обращаюсь к справочным документам, а к книге обращаюсь только в том случае, если ее нет в документации.

...