java - 带有 @Transactional 的 EntityManager persist() 不会抛出 DataIntegrityViolationException

标签 java sql hibernate spring-boot

我们有 EntityManager persist() 和 @Transactional。如果插入的数据超过列长度,则 persist 不会抛出 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不是提交持久化操作吗?为什么要花这么长时间才能抛出异常?

感谢您的帮助。

附注- 我们肯定会检查数据长度。

最佳答案

persist() 只会使对象被管理和持久化,在事务上下文关闭之前,它实际上不会对数据库执行任何操作。要强制立即与数据库同步,请在 persist() 之后调用 flush()。这将导致立即抛出异常。

关于java - 带有 @Transactional 的 EntityManager persist() 不会抛出 DataIntegrityViolationException,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57788687/

相关文章:

java - 如何在 Android 中设置警告框,是否有任何 API 可以将数据从应用程序发送到 URL

java - 在 Java 中使用 XPath 解析 SOAP 消息

java - 停止或重新部署时出现内存泄漏 - Spring 3.1.2、Hibernate 4.1.0、Spring Data-Jpa 1.1.0、Tomcat 7.0.30

java - 如何将 JodaTime 与 Spring 和 Hibernate 一起使用?

mysql - JPA/Hibernate/mySql 中没有持久化数据

java - 如何找到存储在同一行mysql的2列中的日期差异

sql命令占用大量空间

mysql - 如何从多个表中求和多个计数

php - 使用短语搜索mysql数据库

java - HQL 从多个表中选择