【问题标题】:org.springframework.dao.DataIntegrityViolationException after update spring-boot from 2.1.x to 2.2.x using hibernate and spring-boot-data-jpaorg.springframework.dao.DataIntegrityViolationException 在使用 hibernate 和 spring-boot-data-jpa 将 spring-boot 从 2.1.x 更新到 2.2.x 之后
【发布时间】:2020-05-29 02:05:25
【问题描述】:

当尝试使用 JPA 将多个对象插入 MySQL 时,尝试将 spring-boot 从版本 2.1.12 更新到 2.2.4 时遇到 DataIntegrityViolationException。

示例对象:

@Data
@Entity
@AllArgsConstructor
@NoArgsConstructor
@Builder(toBuilder = true)
@Table(name = "user")public class User {

    @Id
    @Column(name = "id")
    @JsonProperty("id")
    private String id;

    @PrimaryKeyJoinColumn
    @OneToOne(cascade = CascadeType.ALL)
    @JsonProperty("status")
    private UserStatus status;

}

和用户状态:

@Data
@Entity
@AllArgsConstructor
@NoArgsConstructor
@Table(name = "user_status")
public class UserStatus {

    @Id
    @Column(name = "id")
    @JsonProperty("id")
    private String id;

    public UserStatus(String userId) {
        this.id = userId;
    }

}

要将对象插入 mysql,我使用默认的 jpa 存储库:

@Repository
public interface UserRepository extends JpaRepository<User, String> { 
}

使用 spring-boot-2.1.x userRepository.save(user) 可以正常工作,但使用 2.2.x 会引发此异常:

org.springframework.dao.DataIntegrityViolationException: could not execute statement; SQL [n/a]; constraint [null]; nested exception is org.hibernate.exception.ConstraintViolationException: could not execute statement

在日志中有此详细信息:

Cannot add or update a child row: a foreign key constraint fails (`test`.`user_status`, CONSTRAINT `user_status_ibfk_1` FOREIGN KEY (`id`) REFERENCES `user` (`id`) ON DELETE CASCADE)

如果启用spring.jpa.show-SQL: true,我发现使用spring-boot-2.2.x 时不会插入User 实体,但使用旧的spring 是。

我没有发现 spring-boot 连接到 hibernate 有任何重大变化,并且在相应更新后 hibernate 本身也没有重大变化。 有没有在发行说明中描述的更新?

【问题讨论】:

  • 你使用的是spring-boot-starter-data-jpastarter吗?
  • 我一直不明白为什么当 JdbcTemplate 可用时 Spring Boot 用户会立即使用 JPA,尤其是对于像这样的简单模式。
  • @duffymo 我也是,但这是我们必须支持一段时间的遗留代码:(
  • @Anton 我的回答对您有帮助吗,因为很可能是您的情况?无论如何,请分享您的想法以解决您的问题
  • @EugeneKortov 非常感谢,它终于有所帮助。要使用它,我必须稍微改变 UserStatus 对象的结构,在 UserStatus 对象中添加对 User 对象的引用。然后你的解决方案完美地找到了。显然,我们在项目中做错了。

标签: java hibernate spring-boot jpa spring-boot-jpa


【解决方案1】:

spring-boot 2.1.12 使用 Hibernate 5.3.15.Final 而 spring-boot 2.2.4 使用 Hibernate 5.4.10.Final

您的问题似乎类似于 Hibernate 问题 HHH-13413 HHH-13171

原因在于 5.4.0.CR1 中引入的修复 HHH-12436,因此从那时起,当未提供 @OneToOne(mappedBy ="") 时,一对一映射不起作用。

正如我从 JIRA 的讨论中了解到的,现在这不是一个错误。有一个错误,他们像这样修复了它。我想@PrimaryKeyJoinColumn 存在一些误解,所以人们没有正确使用它。

我想这会解决问题

@OneToOne(mappedBy = "user", cascade = CascadeType.ALL)
@JsonProperty("status")
private UserStatus status;

【讨论】:

    猜你喜欢
    • 2019-01-22
    • 2015-04-04
    • 2018-01-16
    • 2021-09-13
    • 2017-07-09
    • 2019-10-06
    • 1970-01-01
    • 2015-11-28
    • 1970-01-01
    相关资源
    最近更新 更多