JPA2唯一约束:我真的需要刷新吗?

时间:2010-10-19 10:47:46

标签: java orm jpa jpa-2.0 unique-constraint

我有一个DAO,我需要捕获一个唯一的约束异常。要做到这一点,唯一可行的解​​决方案是在持久化之后刷新我的EntityManager。只有这样我才能进入一个catch块,我必须过滤掉异常。而且,我的DAO方法需要包含在事务中(REQUIRES_NEW),否则我会有RollBackException。

我做错了吗?

try {
        em.persist(myObject);
        em.flush();
    } catch (PersistenceException ex) {
        if (ex.getCause() != null) {
            String cause = ex.getCause().toString();
            if (cause != null) {
                if (cause.contains("org.hibernate.exception.ConstraintViolationException")) {
                    logger
                            .error("org.hibernate.exception.ConstraintViolationException: possible unique constraint failure on name");
                    throw ex;
                }
            }
        }
    }

1 个答案:

答案 0 :(得分:2)

  

我做错了吗?

EntityManager#persist()不会触发立即插入(除非您使用IDENTITY策略)。因此,如果您想实际将内存中的更改写入数据库并有机会捕获约束违规,则必须“{1}}”手动“(尽管即使这样做也不能严格保证任何内容,您的数据库可以配置为使用延迟约束)。

换句话说,你正在做的是IMO才是正确的方法。


  

我有一个带有@Transactional的服务方法(REQUIRED),名为addNewObject()。在这种方法中,会发生一些可能引发异常的事情(从而回滚事务)。其中一个调用是对DAO方法addObject的调用。由于唯一约束,这个可能会失败。现在,如果我进行刷新,如果没有唯一的违规,该对象将被保留。但是,在服务中可能仍有其他因素导致该方法抛出异常。

我认为你让flush()flush感到困惑。如果在commit之外出现问题并抛出不可恢复的异常(但在同一事务中),则将回滚整个事务,包括与addObject调用相对应的INSERT语句。总结一下,persist()!= flush