Hibernate声明性事务异常不抛出的问题

在ssh架构中,假设一个Controller注入并调用了一个Service,而Service上配置了声明性事务,代码如下:

@Service
@Transactional
public class NodeServiceImpl extends CommonServiceImpl
{
    private static final Logger log = Logger.getLogger(NodeServiceImpl.class);
    
    public void save(WfNodeEntity node)
    {
        node.setId("1");
        try
        {
            this.save(node);
        } catch (Exception e) 
        {
            log.info("错误:这里发生异常了!" + e.getMessage());
            e.printStackTrace();
        }
    }

}

我们故意让this.save(node)代码行发生错误(比如把(WfNodeEntity的@column故意改成一个不存在的字段),那么,会发生异常吗?log.info会记录下日志吗?答案是不会的。

因为我们采用的是hibernate,并且是声明性事务,因此,程序执行this.save(node)语句,只是把node放入了hibernate的缓存区域的一块持久化区域,并不会立即执行insert语句。因此程序不会发生异常,log.info()自然就不会执行。

这个save(WfNodeEntity node)方法完成后,返回到Controller层,事务才会被提交,此时hibernate才会刷新、清理缓存,开始执行insert语句,所以此时才会在Controller层抛出异常,并且从控制台是无法看到是save(WfNodeEntity node)方法的哪一行代码发生了异常。

如果想确切的记录this.save(node)这一行发生异常怎么办呢?很简单,在其后追加一行代码即可,即

        try
        {
            this.save(node);
            this.flush();
        } catch (Exception e) 
        {
            log.info("错误:这里发生异常了!" + e.getMessage());
            e.printStackTrace();
        }

这样由于进行了this.flush(),hibernate 会立即执行insert语句,并发生异常,然后被catch住,log.info就能准确记录下错误信息了。

你可能感兴趣的:(Hibernate声明性事务异常不抛出的问题)