Spring JPA DAO中的Transactionmanager

时间:2014-05-24 00:23:16

标签: spring hibernate jpa

我在spring和JPA中使用了以下配置,

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
    http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.0.xsd">


<bean id="entityManger"
    class="org.springframework.orm.jpa.LocalEntityManagerFactoryBean">
    <property name="persistenceUnitName" value="JPA-01" />
</bean>

<bean id="dao" class="springdao.MessageDAO" />

</beans>

我的persistence.xml是,

<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.1"
    xmlns="http://xmlns.jcp.org/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence http://xmlns.jcp.org/xml/ns/persistence/persistence_2_1.xsd">
    <persistence-unit name="JPA-01">
        <provider>org.hibernate.ejb.HibernatePersistence</provider>
        <properties>
            <property name="hibernate.archive.autodetection" value="class, hbm" />
            <property name="hibernate.show_sql" value="true" />
            <property name="hibernate.format_sql" value="true" />
            <property name="hibernate.connection.driver_class" value="com.mysql.jdbc.Driver" />
            <property name="hibernate.connection.url" value="jdbc:mysql://localhost:3306/Hibernate" />
            <property name="hibernate.connection.username" value="root" />
            <property name="hibernate.connection.password" value="password" />
            <property name="hibernate.c3p0.min_size" value="5" />
            <property name="hibernate.c3p0.max_size" value="20" />
            <property name="hibernate.c3p0.timeout" value="300" />
            <property name="hibernate.c3p0.max_statements" value="50" />
            <property name="hibernate.c3p0.idle_test_period" value="3000" />
            <property name="hibernate.dialect" value="org.hibernate.dialect.MySQLDialect" />
            <!-- <property name="hibernate.hbm2ddl.auto" value="create" />
             -->
        </properties>

    </persistence-unit>
</persistence>

我的junit是,

package test;

import junit.framework.Assert;
import model.Message;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

import dao.MessageDAO;

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations={"classpath:SpringDAOTest.xml"})
public class SpringDAOTest {


    @Autowired
    springdao.MessageDAO dao;





    @Test
    public void testGetMessageById() {
        Message message = dao.getMessageById("1");
        Assert.assertNotNull(message);
        System.out.println(message);
    }

    @Test
    public void testPersistMEssage() {
        Message message = new Message();
        message.setMessage("Hello World This is the second Message");
        dao.persistMessage(message);

    }

    @Test
    public void testUpdateMessage() {
        String updatedMessage = "Updated Message for ID 1";
        dao.updateMessage(updatedMessage, 1);

    }

    // TODO updateMessageID
    @Test
    public void testUpdateMessageID() {
        String updatedMessage = "Updated Message for ID 1 with 25";
        dao.updateMessageID(updatedMessage, 1);

    }

}

我有以下问题,

  1. 我已经自动连接了持久化上下文。我想声明当前的持久化上下文是否已关联?
  2. 我没有使用applicationcontext.xml中配置的事务管理器。只需通过注释类,我就可以为服务配置事务。
  3. 我想得到实体事务id,所以我想断言整个服务(涉及很多daos)使用相同的事务。

2 个答案:

答案 0 :(得分:1)

1)在MessageDAO中为EntityManager提供一个getter方法并使用assertNotNull(虽然不建议也不需要测试这个场景;你应该只测试你的业务逻辑并相信框架会正确关联EntityManager)

2)从数据库读取数据不需要交易。但是,将数据写入数据库确实需要事务处理。因此,您需要为持久性操作配置事务管理器,如下所示

<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"/>
</bean>

您可以通过两种方式在事务下执行方法

  • XML配置
  • @Transactional annotation

使用@Transactional在没有TransactionManager的情况下注释您的方法将默默地忽略它。

3)我不知道检索交易ID。 但是,使用像Spring这样的框架的主要目的是有人已经为您测试了基础架构代码,您可以专注于仅测试您的业务逻辑。试图重新测试可能不是一个好主意。

答案 1 :(得分:0)

当您使用实体管理器作为数据访问API时,您可以使用以下事务管理器配置

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

默认情况下,如果命名为“dataSource”和“entityManagerFactory”,则此事务管理器将获取数据源bean。此事务管理器变量将实体管理器与指定的实体管理器工厂绑定到当前线程。另外值得看一下documentation