Hibernate cascade remove ConstraintViolationException
Asked Answered
T

2

6

It seems the situation is simply (but it does not work). Db part (EVENT_ID is foreign key. FK_RR_E_CI constraint references on EVENT table)

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

Java part:

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

If I try to delete event object It will return:

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

SAVE and UPDATE operations work correctly.


What should I change in my mapping to be able use cascade removal? I know that I should use @OnDelete(action=OnDeleteAction.CASCADE) but I can't understand how to use it...

Twentyfourmo answered 5/7, 2017 at 21:43 Comment(1)
Please see minimal reproducible example. Show actual DDL, table contents, desired output & query.Bowshot
C
3

Instead of using cascade = CascadeType.ALL attribute in the @OneToMany annotation, use Hibernate's @Cascade() annotation like this:

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

Because cascade = CascadeType.ALL is a JPA option, so when Hibernate session tries to delete the object, it will search for a Hibernate Cascade, it won't find it, that's why you should use @Cascade.

For further reading take a look at Cascade – JPA & Hibernate annotation common mistake, it gives a better explanation.

Cyprinodont answered 5/7, 2017 at 21:58 Comment(1)
Any way same exception because of Caused by: java.sql.SQLIntegrityConstraintViolationException: ORA-02292: integrity constraint (MY_SCHEMA.FK_RR_E_CI) violated - child record found - hibernate should delete at first collection RecurrentRule and than EventTwentyfourmo
T
2

It seems has an issue with deep of relations. In hierarchy above event I have calendar before calendar I have profile. To resolve this relations I've used @OnDelete(action = OnDeleteAction.CASCADE) but it was not enough for my case. For described case Event <=> RecurrentRule relation I've implemented listener for Event and I've used one @EntityListeners({EntityEventJpaCallbacksListener.class}) see import [javax.persistence.EntityListeners][1];

@Component
public class EntityEventJpaCallbacksListener {
    @PreRemove
    void preRemove(Event event) {
        ContextAware.getBean(RecurrentRuleRepository.class).deleteByEvent(event);
    }
}
Twentyfourmo answered 7/7, 2017 at 14:11 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.