在ConstraintViolationException之后,Hibernate会话无效

时间:2011-02-24 18:58:46

标签: hibernate

在抛出约束违规异常后,有没有办法继续使用线程绑定的hibernate会话?我在这里举一个简短的例子:

    Parent other=service.load(33); // loads a new parent
    try {
        Parent p=new Parent();
        p.setName("A name");
        service.save(p); // a @Transactional spring service class, throws ConstraintViolationException - name should be at least 15 characters long
    } catch (ConstraintViolationException e){
        // i would like to handle validation errors and proceed normally
        // but the session is allready closed here
    }
    System.out.println("Children: " + other.getChildren()); // lazy initialization exception, even when using opensessioninview

从现在开始,hibernate会话完全没用,即使对于只读操作,比如使用OpenSessionInView模式在视图中呈现延迟集合。

2 个答案:

答案 0 :(得分:12)

Session的文档声明如果会话抛出异常,则必须回滚事务并丢弃会话。发生异常后,Session的内部状态可能与数据库不一致。

AFAIK,没有办法从中恢复,我记得有人在工作警告我不要使用session-per-request / OpenSessionInView模式,因为这些问题。

答案 1 :(得分:5)

使用StatelessSession而不是Session。这就是诀窍。

使用StatelessSession,您可以在SQL之后继续执行任何异常(即使在一个事务中 - hibernate也不会执行提交/回滚)。这是批量更新/插入或检查是否违反了唯一约束的理想选择。

但要注意,与正常会话相比,StatelessSession有许多限制。请参考Hibernate documentaion / Javadocs。