Java 事务内部的Spring DAO异常转换
我将Spring3.1.2与Hibernate4一起使用 我有一个用Java 事务内部的Spring DAO异常转换,java,spring,exception,dao,Java,Spring,Exception,Dao,我将Spring3.1.2与Hibernate4一起使用 我有一个用@Repository注释的DAO实现类MyDaoImpl,以便启用异常转换。我有一个服务类MyService,用@Transactional注释如下: public class MyService implements IMyService { private MyDao myDao; @Autowired public void setMyDao(MyDao dao) { this.
@Repository
注释的DAO实现类MyDaoImpl
,以便启用异常转换。我有一个服务类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);
}
}
@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
}
}
我编写了一个单元测试类MyServiceTest
,如下所示:
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);
}
}
@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
注释,但我不会从回滚特性中受益
你有什么建议
EDIT:我已将上下文中声明的
SessionFactory
添加到测试类中,以便访问当前会话进行刷新
一些额外的解释:在本例中,我在刷新会话(在事务内部)时得到异常。我刷新会话以避免误报,正如文档中所解释的那样。另外,由于默认传播是必需的,因此
testCreateA()
事务也用于调用createA()
,因此在testCreateA()
返回之前(通常)不会刷新更改。是否添加了持久性异常TranslationPostProcessor
bean定义?像
<!--
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" />
从
自动应用持久性异常的Bean后处理器
翻译到任何带有@Repository
注释的bean,添加
一个对应的持久性异常TranslationAdvisor
到暴露的
代理(现有AOP代理或新生成的
实现所有目标的接口)
将本机资源异常转换为Spring的DataAccessException
等级制度自动检测实现
PersistenceExceptionTranslator
接口,随后会询问
翻译候选例外
我在医生上没看到这个。您确定它仍然相关吗?@Mickael:AFAIK
@Repository
表示异常转换的类,并PersistenceExceptionTranslationPostProcessor
执行转换任务。检查我的编辑。我已经编辑了我的问题。添加后处理器并不能解决我的问题,我仍然在测试用例中得到一个特定于Hibernate的异常。