【发布时间】:2014-08-27 14:03:04
【问题描述】:
使用 spring 4.0.6.RELEASE、Hibernate 4.3.6.Final 和 hsqldb 2.3.2。我的集成测试如下所示;
@Test(expected = DataIntegrityViolationException.class)
public final void testDuplicateItems() {
final ServerEntity serverEntity1 = new ServerEntity("DuplicateItem");
opService.save(serverEntity1);
opService.save(serverEntity1);
}
这按预期工作。但是,当我运行我的独立 java 组件时,我可以保存第一项,第二项是重复的,但我无法捕获异常。这是日志文件
WARN org.hibernate.engine.jdbc.spi.SqlExceptionHelper: SQL Error: -104, SQLState: 23505
2014-08-27 14:52:06,843 ERROR org.hibernate.engine.jdbc.spi.SqlExceptionHelper: integrity constraint violation: unique constraint or index violation; UK_NFU7LXMMDFVIR1WD08662085N table: SERVERENTITY
[WARNING]
java.lang.reflect.InvocationTargetException
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at org.codehaus.mojo.exec.ExecJavaMojo$1.run(ExecJavaMojo.java:293)
at java.lang.Thread.run(Thread.java:745)
Caused by: org.springframework.dao.DataIntegrityViolationException: could not execute statement; SQL [n/a]; constraint [UK_NFU7LXMMDFVIR1WD08662085N]; nested exception is org.hibernate.exception.ConstraintViolationException: could not execute statement
at org.springframework.orm.hibernate4.SessionFactoryUtils.convertHibernateAccessException(SessionFactoryUtils.java:161)
at org.springframework.orm.hibernate4.HibernateTransactionManager.convertHibernateAccessException(HibernateTransactionManager.java:681)
at org.springframework.orm.hibernate4.HibernateTransactionManager.doCommit(HibernateTransactionManager.java:563)
at org.springframework.transaction.support.AbstractPlatformTransactionManager.processCommit(AbstractPlatformTransactionManager.java:757)
at org.springframework.transaction.support.AbstractPlatformTransactionManager.commit(AbstractPlatformTransactionManager.java:726)
at org.springframework.transaction.interceptor.TransactionAspectSupport.commitTransactionAfterReturning(TransactionAspectSupport.java:478)
at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:272)
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:95)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:207)
at com.sun.proxy.$Proxy38.execute(Unknown Source)
at com.opserver.simpleapp.MainApp.start(MainApp.java:60)
at com.opserver.simpleapp.MainApp.main(MainApp.java:37)
... 6 more
服务和 dao 实现在类级别都有 @Transactional。我有一个调用服务类的组件类,这个组件类不是事务性的!组件类打印响应,这里是否需要刷新会话?
需要弄清楚为什么dao中的save方法没有抛出异常,我实际上可以看到它正在创建一个id然后回滚。
J
我的组件类很基础;
boolean isValid = opServerService.loadXMLFile("Server.xml");
try{
if (isValid) {
System.out.println("Entity has been added");
} else {
System.out.println("Entity has not been added");
}
}catch (Exception ex){
System.out.println("that was a focked up");
}
问题是“实体已添加”被打印到控制台,然后我在控制台中看到上述错误。
DAO 看起来像这样
@Override
@Transactional
public final void save(final ServerEntity serverEntity) throws DataIntegrityViolationException {
LOGGER.debug(">>start(serverEntity=" + serverEntity + ")");
Preconditions.checkNotNull(serverEntity);
this.getCurrentSession().save(serverEntity);
}
在类级别使用@Transactional 的服务方法,如下所示
@Override
public final void save(ServerEntity serverEntity) {
opServerDao.save(serverEntity);
}
组件看起来像这样
@Component
public class AddCommand implements Command {
@Autowired
OpService opService;
public AddServerCommand() {
super();
}
@Override
public void execute(String[] options) {
try{
boolean isValid = opService.save("Server.xml");
if (isValid) {
System.out.println("Entity has been added");
} else {
System.out.println("Entity has not been added");
}
}catch (Exception ex){
System.out.println("Exception found");
}
}
}
【问题讨论】:
标签: spring hibernate hsqldb transactional