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

发布于 2024-07-18 00:19:28 字数 453 浏览 8 评论 0原文

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

我的方法中的样板事务代码量减少到最少的最简单方法是什么?

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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

戏剧牡丹亭 2024-07-25 00:19:28

为了做到这一点,您应该做一些工作,但根本不多。 假设您将使用 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"/>

上面的某些属性可能会更改或根据您的需要添加。 正如您可能已经猜到的,该示例适用于带有 Hibernate 和 PostgreSQL 数据库的 JPA。

现在您可以像这样简单地定义数据访问方法:

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

其中 User 是由您的应用程序定义的 JPA 实体。 您可以在调用 DAO 的管理器/控制器层管理事务 - 事实上我就是这样做的 - 但我将它们放在一起,以免示例过于混乱。

您可能想直接访问而不是我的示例的不错的参考资料是
http://icoloma.blogspot.com/2006/11 /jpa-and-spring-fucking-cooltm_26.html
它引用的前 3 个链接也值得访问。

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.

随遇而安 2024-07-25 00:19:28

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

1) 通过 TransactionTemplate 或 PlatformTransactionManager 进行编程处理 - 较少配置,但具有侵入性

2) 通过 XML 进行声明 - 冗长的 XML,但非侵入性

3) 通过注释进行声明 - 较少使用 XML,但不具有 侵入性你选择

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

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

我总是首先查阅参考文档,并且只查阅文档中没有的书。

Spring provides at least 3 ways of transaction demarcation:

1) Programmatic handling, via TransactionTemplate or PlatformTransactionManager - light on config, but invasive

2) Declarative via XML - verbose XML, but non-invasive

3) Declarative via annotations - light on XML, not invasive

Which one you pick depends on which one best suits your needs, Spring doesn't make that choice for you. From your question, it sounds like the annotation approach is what you're after.

I suggest reading the Spring reference manual, the section of annotation-driven transaction handling. It's clear and concise.

I always consult the ref docs first, and only consult a book if it's not in the docs.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文