2 votes

Org.springframework.dao.DataIntegrityViolationException après la mise à jour de spring-boot de 2.1.x à 2.2.x en utilisant hibernate et spring-boot-data-jpa

En essayant de mettre à jour spring-boot de la version 2.1.12 à la version 2.2.4, je me suis retrouvé bloqué avec une DataIntegrityViolationException lors de l'insertion de plusieurs objets dans MySQL en utilisant JPA.

Exemple d'objet :

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

}

Et le statut de l'utilisateur :

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

}

Pour insérer un objet dans MySQL, j'utilise le repository JPA par défaut :

@Repository
public interface UserRepository extends JpaRepository {
}

Avec spring-boot-2.1.x, userRepository.save(user) fonctionne bien mais avec la version 2.2.x, cela provoque cette 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

Avec ces détails dans le journal :

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)

Si on active spring.jpa.show-SQL: true, je me suis rendu compte qu'avec spring-boot-2.2.x, aucune insertion dans l'entité User ne se fait tandis qu'avec l'ancienne version de spring, ça fonctionne.

Je n'ai trouvé aucun changement majeur dans la connexion entre spring-boot et hibernate, ni aucun changement majeur dans hibernate lui-même après la mise à jour correspondante. Y a-t-il eu des mises à jour non décrites dans les notes de version ?

0voto

Eugene Kortov Points 367

Spring-boot 2.1.12 utilise Hibernate 5.3.15.Final et spring-boot 2.2.4 utilise Hibernate 5.4.10.Final

Votre problème semble similaire aux problèmes de Hibernate HHH-13413 HHH-13171

La raison se trouve dans la correction HHH-12436 qui a été introduite en 5.4.0.CR1 donc depuis cette version, les mappings one-to-one ne fonctionnent pas lorsque @OneToOne(mappedBy ="") n'est pas fourni.

Et d'après ce que j'ai compris des discussions dans JIRA, ce n'est pas un bug maintenant. Il y avait un bug et ils l'ont corrigé de cette façon. Je suppose qu'il y a une incompréhension avec @PrimaryKeyJoinColumn, donc les gens ne l'utilisent pas correctement.

Je pense que cela résoudra le problème

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

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X