在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之间(在坚持之前)。哪种方法更好(冲洗-失去性能,查找-对数据库的冗余请求)?另外,如果我在这里某个地方出错,请指点我。

最佳答案

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

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

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

10-06 11:27