我正在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()
返回之前(通常)不会刷新更改。
答案 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
层次结构。自动检测实现的beanPersistenceExceptionTranslator
接口,随后被询问 翻译候选人例外