javahibernatespring-bootjpaspring-boot-jpa

org.springframework.dao.DataIntegrityViolationException after update spring-boot from 2.1.x to 2.2.x using hibernate and spring-boot-data-jpa


When trying to update spring-boot from version 2.1.12 to 2.2.4 got stuck on DataIntegrityViolationException when try to insert multiple objects into MySQL using JPA.

Example object:

@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;

}

And user 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;
    }

}

To insert object to mysql I use default jpa repository:

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

With spring-boot-2.1.x userRepository.save(user) works fine but with 2.2.x it raises this exception:

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

With this details in log:

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)

If enable spring.jpa.show-SQL: true I found out that with spring-boot-2.2.x no insertion on User entity is happening but with old spring it is.

I didn't find any major change in spring-boot connecting to hibernate as well as no major change in hibernate itself after the corresponding update. Is there anything updated which is not described in release notes?


Solution

  • spring-boot 2.1.12 uses Hibernate 5.3.15.Final and spring-boot 2.2.4 uses Hibernate 5.4.10.Final

    Your issue seems similar to Hibernate issues HHH-13413 HHH-13171

    The reason is in the fix HHH-12436 which was introduced in 5.4.0.CR1 so since then one-to-one mappings don’t work when @OneToOne(mappedBy ="") didn’t provided.

    And as I understood from disscussions in JIRA it's not a bug now. There was a bug and they fixed it like so. I guess there is some misunderstanding with @PrimaryKeyJoinColumn so people doesn't use it right.

    I guess this will solve the problem

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