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...
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.
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);
}
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.