Spring4 +和Hibernate 4交易

时间:2014-08-27 14:03:05

标签: spring hibernate hsqldb transactional

使用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

service和dao实现在类级别都有@Transactional。我是一个调用服务类的组件类,这个组件类不是事务性的!组件类打印响应,是否需要在此处刷新会话?

需要弄清楚为什么dao中的save方法没有抛出异常,我实际上可以看到它正在被创建然后回滚。

Ĵ

我的组件类非常基础;

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看起来像这样

@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");
        }
    }

}

2 个答案:

答案 0 :(得分:0)

您应该在调用该服务的组件中捕获您的异常。

答案 1 :(得分:0)

找不到applicationContext.xml中的解决方案。 opService周围的包装try / catch现在捕获异常。需要实现我自己的自定义异常处理程序,但至少我知道组件类正在处理从服务类抛出的异常。

感谢您的帮助。

Ĵ