Java jpa刷新或在持久化之前查找

Java jpa刷新或在持久化之前查找,java,spring,hibernate,jpa,Java,Spring,Hibernate,Jpa,在Spring声明性事务管理中,当您试图持久化数据库中已经存在的某个实体时,您只能在Spring事务提交期间获得DataIntegrityViolationException。因此,此方法不起作用,catch大括号中的异常在此处不会被捕获: @Repository public class UserDAOImpl implements UserDAO { @PersistenceContext EntityManager em; @Override p

在Spring声明性事务管理中,当您试图持久化数据库中已经存在的某个实体时,您只能在Spring事务提交期间获得DataIntegrityViolationException。因此,此方法不起作用,
catch
大括号中的异常在此处不会被捕获:

@Repository
public class UserDAOImpl implements UserDAO {

    @PersistenceContext
    EntityManager em;

    @Override
        public void createUserRole(String role) throws RoleAlreadyExistsException {
            try {
                UserRole userRole = new UserRole(role);
                em.persist(userRole);
            } catch (Exception e) {
                throw new RoleAlreadyExistsException();
            }
        }
}
只有在以下情况结束时:

@Service("userService")
public class UserService 
    @Transactional
        public void createUserRole(String role) throws RoleAlreadyExistsException {
            userDao.createUserRole(role);
        }
}
我找到了几个解决方法:

  • 不使用@Transaction
  • 使用冲洗
  • 调用服务时捕获异常
  • 三思而后行

现在我在考虑em.flush和em.find(在persist之前)。使用哪种方法更好(刷新-丢失性能,查找-对数据库的冗余请求)?此外,如果我在这里的某个地方出错,请指出我。

有时,刷新可能有助于在正在进行的事务之间保留数据,然后最终提交更改。因此,如果之后出现问题,您还可以回滚以前的更改,例如批插入/更新

因此,当您调用
em.flush()
时,将在数据库中执行插入/更新/删除关联实体的查询。此时将知道任何约束失败(列宽、数据类型、外键)


在您的情况下,我将使用flush。

我强烈建议不要使用flush-使用flush仍然会导致您在昂贵的事务中执行业务逻辑。通常,您应该尽量避免在业务逻辑中抛出异常,并在执行风险操作之前检查所有数据输入(通过find)。它简化了您的应用程序逻辑,使您的意图更加清晰,并使您的代码更易于维护。此外,我强烈建议您在数据访问中使用“>Spring Data JPA,它可以为您解决这些问题。