3

我正在Spring 3.1.2使用Hibernate 4.

我有一个MyDaoImpl带有注释的 DAO 实现类,@Repository以便启用异常翻译。我有一个MyService注释@Transactional如下的服务类:

public class MyService implements IMyService {

    private MyDao myDao;

    @Autowired
    public void setMyDao(MyDao dao) {
       this.myDao = dao;
    }

    @Override
    @Transactional
    public void createA(String name)
    {
        A newA = new A(name);
        this.myDao.saveA(newA);
    }
}

我编写了一个单元测试类MyServiceTest,如下所示:

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = { "classpath:beans.xml" })
@Transactional
@TransactionConfiguration(defaultRollback = true)
public class MyServiceTest implements IMyServiceTest {

    private IMyService myService;

    private SessionFactory sessionFactory;

    @Autowired
    public void setMyService(IMyService myService)
    {
        this.myService = myService;
    }

    @Autowired
    public void setSessionFactory(SessionFactory sessionFactory)
    {
        this.sessionFactory = sessionFactory;
    }

    @Test
    @Override
    public void testCreateA()
    {
       //Assume that there is already a row of table A with the name "A1"
       //so I expect to get a Spring DataAccessException (or subtypes) 
       //when the session is flushed
       this.myService.createA("A1");

       this.sessionFactory.getCurrentSession().flush();

       //asserts
    }
}

当我运行测试时,我得到一个 Hibernate specific exception ConstraintViolationException。我在论坛上发现这是因为翻译系统发生在事务之外,所以在这种情况下是在testCreateA()返回之后。我不知道这是否是真正的原因,但如果是,则意味着我无法测试翻译是否适用于我的 DAO。一种解决方案是从我的单元测试中删除@Transactional注释,但我不会从回滚功能中受益。

你有什么建议?


编辑:我已将SessionFactory上下文中的声明添加到测试类中,以便我可以访问当前会话以进行刷新。

一些额外的解释:在这种情况下,当会话被刷新(在事务内部)时,我得到了异常。我刷新会话以避免误报,正如文档中所解释的那样。此外,由于默认传播是必需的,因此testCreateA()事务也用于调用createA(),因此更改不会刷新(通常)直到testCreateA()返回。

4

1 回答 1

1

您是否添加了PersistenceExceptionTranslationPostProcessorbean 定义?喜欢

   <!--
        Post-processor to perform exception translation on @Repository classes
        (from native exceptions such as JPA PersistenceExceptions to
        Spring's DataAccessException hierarchy).
    -->
    <bean class="org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor" />

来自Spring 文档

Bean 后处理器,它自动将持久性异常转换应用于任何带有@Repository注释的 bean,添加一个对应PersistenceExceptionTranslationAdvisor于暴露的代理(现有的 AOP 代理或新生成的实现所有目标接口的代理)。

将本机资源异常转换为 Spring 的DataAccessException 层次结构。自动检测实现接口的 bean, PersistenceExceptionTranslator随后要求这些 bean 转换候选异常

于 2012-08-27T11:25:55.543 回答