Spring事务中的DAO异常翻译

时间:2012-08-27 10:55:12

标签: java spring exception dao

我正在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的异常ConstraintViolationException。我在论坛上发现这是因为翻译系统发生在交易之外,所以在这种情况下testCreateA()返回后。我不知道这是不是真正的原因,但如果是,那就意味着我无法测试翻译是否适用于我的DAO。一种解决方案是从我的单元测试中删除@Transactional注释,但我不会从回滚功能中受益。

你有什么建议?


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

一些额外的解释:在这种情况下,我在刷新会话时遇到异常(在事务内部)。我刷新会话以避免误报,因为它在文档中有解释。此外,由于默认传播是必需的,testCreateA()事务也用于调用createA(),因此在testCreateA()返回之前(通常)不会刷新更改。

1 个答案:

答案 0 :(得分:1)

你添加了PersistenceExceptionTranslationPostProcessor bean defination吗?像

   <!--
        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 doc

  

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

     

将原生资源异常转换为Spring DataAccessException   层次结构。自动检测实现的bean   PersistenceExceptionTranslator接口,随后被询问   翻译候选人例外