有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

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

我有一个DAO,需要捕获一个唯一的约束异常。要做到这一点,唯一有效的解决方案是在事件发生后刷新EntityManager。只有这样,我才能进入一个catch块,在那里我必须过滤掉异常。而且,我的DAO方法需要包装在一个事务中(需要_NEW),否则就会出现回滚异常

我做错什么了吗

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) 个答案

  1. # 1 楼答案

    Am I doing something wrong?

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

    换句话说,你所做的正是正确的方向


    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.

    我认为你把flushcommit搞混了。如果在addObject之外发生错误并抛出不可恢复的异常(但在同一事务内部),整个事务将回滚,包括与persist()调用对应的INSERT语句。总之,flush=commit