带有@Transactional的EntityManagerpersist()不会引发DataIntegrityViolationException

时间:2019-09-04 12:44:46

标签: java sql hibernate spring-boot

我们有带@Transactional的EntityManagerpersist()。如果插入的数据长度超过列长度,则persistent不会抛出DataIntegrityViolationException。当具有@Transactional的2级上一级父方法返回时,将引发该错误。

class Worker {

    @Transactional
    public Integer createEmployee(String name) { 
        // employeeId is generated after checking if employee exists or not
        saveEmployee(name, employeeId);
        send_to_third_party(employeeId);
        return employeeId;
    }

    saveEmployee(String name, Integer employeeId){
        Employee em = new Employee();
        // Get other data for employee like department etc.
        dao.persist(employee);
    }
}

class Dao {
    @autowired
    EntityManager em;

    @Transational
    public void persist(Object object) {
        try{
            em.persist(object);
            log("successful");
        }
        catch(RuntimeException ex) {
            log("persist failed");
            throw ex;
        }
    }
}

如代码中所示,即使出现数据长度大于列长度之类的错误,saveEmployee也将返回成功。将employeeId发送给第三方并进行处理。当createEmployee返回employeeId时,它将引发异常“ DataIntegrityViolationException”并显示消息“字符串或二进制数据将被截断”。最后,在第三方进行处理的过程中,员工没有保存到我们的数据库中,这会导致系统不匹配以及进一步的错误。

dao.persist()中的@Transactional是否提交持久操作?为什么引发异常需要这么长时间?

谢谢您的帮助。

P.S。 -我们肯定会检查数据长度。

1 个答案:

答案 0 :(得分:2)

persist()仅使对象成为托管对象和持久对象,直到关闭事务上下文之前,它实际上不会对数据库做任何事情。要强制与数据库立即同步,请在flush()之后调用persist()。这将导致立即引发异常。