2

Il semble que la situation soit simple (mais cela ne marche pas). partie Db (EVENT_ID est la clé étrangère FK_RR_E_CI références de contraintes sur la table EVENT.)Hibernate cascade remove ConstraintViolationException

|-------|   |----------------| 
| EVENT | 1 ------ ∞ | RECURRENT_RULE | 
|-------|   |----------------| 
| ID |   | ID    | 
|-------|   | EVENT_ID  | 
         |----------------| 

Java partie:

@Entity 
public class Event { 
    @OneToMany(cascade = CascadeType.ALL, orphanRemoval = true, mappedBy = "event") 
    private Set<RecurrentRule> recurrentRules = new HashSet<>(); 
} 

@Entity 
public class RecurrentRule { 
    @ManyToOne 
    @JoinColumn(columnDefinition = "event_id") 
    private Event event; 
} 

Si je tente de supprimer objet événement se reconnectera:

could not execute statement; SQL [n/a]; constraint [MY_SCHEMA.FK_RR_E_CI]; 
nested exception is org.hibernate.exception.ConstraintViolationException: could not execute statement 
... 
java.sql.SQLIntegrityConstraintViolationException: ORA-02292: integrity constraint (MY_SCHEMA.FK_RR_E_CI) violated - child record found 
Les opérations

SAVE et UPDATE fonctionnent correctement.


Que dois-je changer dans ma correspondance pour être en mesure l'utilisation suppression en cascade? Je sais que je devrais utiliser @OnDelete(action=OnDeleteAction.CASCADE) mais je ne comprends pas comment l'utiliser ...

+0

S'il vous plaît voir [mcve]. Afficher le DDL réel, le contenu de la table, la sortie et la requête souhaitées. – philipxy

Répondre

2

Au lieu d'utiliser cascade = CascadeType.ALL attribut dans l'annotation @OneToMany, utilisez l'annotation @Cascade() de mise en veille prolongée comme ceci:

@OneToMany(orphanRemoval = true, mappedBy = "event") 
@Cascade({CascadeType.ALL}) 
private Set<RecurrentRule> recurrentRules = new HashSet<>(); 

Parce que cascade = CascadeType.ALL est une option JPA, donc quand la session Hibernate essaye de supprimer l'objet, elle va chercher une Hibernate Cascade, elle ne le trouvera pas, c'est pourquoi vous devriez utiliser @Cascade.

Pour en savoir plus, jetez un oeil à Cascade – JPA & Hibernate annotation common mistake, cela donne une meilleure explication.

+1

Toute façon même exception à cause de 'Causé par: java.sql.SQLIntegrityConstraintViolationException: ORA-02292: contrainte d'intégrité (MY_SCHEMA.FK_RR_E_CI) violé - enregistrement enfant trouvé' - Hibernate devrait supprimer à la première collection' RecurrentRule 'et' Event' – Sergii

1

Il semble qu'il y ait un problème avec les relations profondes. Dans la hiérarchie ci-dessus event J'ai calendar avant le calendrier, j'ai profile. Pour résoudre ces relations j'ai utilisé @OnDelete(action = OnDeleteAction.CASCADE) mais ce n'était pas assez pour mon cas. Pour décrit le cas Event < =>RecurrentRule relation que j'ai mis en écoute pour l'événement et je l'ai utilisé un @EntityListeners({EntityEventJpaCallbacksListener.class}) voir import [javax.persistence.EntityListeners][1];

@Component 
public class EntityEventJpaCallbacksListener { 
    @PreRemove 
    void preRemove(Event event) { 
     ContextAware.getBean(RecurrentRuleRepository.class).deleteByEvent(event); 
    } 
}