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

我有一个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;
                }
            }
        }
    }

最佳答案

Am I doing something wrong?

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

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

I have a service method with a @Transactional on it (REQUIRED) called addNewObject(). In this method some stuff happens that might throw an exception (and thus rollback the transaction). One of these calls is a call to the DAO method addObject. This one might fail because of the unique constraint. Now, if I do flush, the object will be persisted if there is no unique violation. However, within the service there might still be something else that causes the method to throw an exception.

我认为你混淆了刷新和提交.如果addObject外部出现问题并抛出一个不可恢复的异常(但在同一个事务中),整个事务将被回滚,包括对应于persist()调用的INSERT语句.总结一下,flush!= commit.

点赞