使用Spring自动进行Hibernate事务管理?

Jam*_*hon 11 spring dao hibernate transactions

Spring框架与事务处理有多远?我阅读了"Spring In Action"一书的建议,其中的例子是您创建了DAO方法,这些方法不需要担心会话和事务管理,只需在XML中设置会话工厂和事务模板,然后将它们连接到DAO中.另一方面,SpringSource.org的文档表明需要大量的XML和/或注释来实现这一点.

这里的真相是什么,我可以采用最简单的方式采用代码

get session from sessionfactory
open transaction
preform database actions
commit transaction with error handling
Run Code Online (Sandbox Code Playgroud)

并使它成为公正

preform database actions
Run Code Online (Sandbox Code Playgroud)

将我的方法中的锅炉板事务代码量减少到最少?

top*_*hef 11

你应该做一些工作才能做到这一点,但它根本不是很多.据说,您将使用JPA选择您自己的提供程序,例如Hibernate.然后,您需要在META-INF文件夹中放置定义持久性单元的persistence.xml:

<?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>
Run Code Online (Sandbox Code Playgroud)

接下来,在您使用的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"/>
Run Code Online (Sandbox Code Playgroud)

以上某些属性可能会根据您的需要进行更改或添加.您可能已经猜到了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);
    }
 }
Run Code Online (Sandbox Code Playgroud)

其中User是由您的应用程序定义的JPA实体.您可以在管理器/控制器层管理调用DAO的事务 - 实际上我是这样做的 - 但是我把它放在一起这里不要太过混乱.

您可能希望直接参考而不是我的示例的好参考是 http://icoloma.blogspot.com/2006/11/jpa-and-spring-fucking-cooltm_26.html 它引用的前3个链接值得去同样.


ska*_*man 10

Spring提供至少3种事务划分方式:

1)通过TransactionTemplate或PlatformTransactionManager进行编程处理 - 点亮配置,但是入侵

2)通过XML声明 - 详细XML,但非侵入性

3)通过注释声明 - 点亮XML,而不是侵入性

您选择哪一个取决于哪一个最适合您的需求,Spring不会为您做出选择.从您的问题来看,听起来就像注释方法就是您所追求的.

我建议阅读Spring参考手册,注释驱动的事务处理部分.它简洁明了.

我总是先咨询参考文档,如果它不在文档中,则只查阅一本书.