JPA CascadeType.ALL does not delete orphans
If you are using it with Hibernate, you'll have to explicitly define the annotation CascadeType.DELETE_ORPHAN
, which can be used in conjunction with JPA CascadeType.ALL
.
If you don't plan to use Hibernate, you'll have to explicitly first delete the child elements and then delete the main record to avoid any orphan records.
execution sequence
- fetch main row to be deleted
- fetch child elements
- delete all child elements
- delete main row
- close session
With JPA 2.0, you can now use the option orphanRemoval = true
@OneToMany(mappedBy="foo", orphanRemoval=true)
Cascade.Type = ALL does not delete all child rows before trying to delete its own row
You can try to use @OnDelete
. As it's stated in the documentation:
... the
@OnDelete
cascade is a DDL-level FK feature which allows you to remove a child record whenever the parent row is deleted.So, when annotating the
@ManyToOne
association with@OnDelete(action = OnDeleteAction.CASCADE)
, the automatic schema generator will apply theON DELETE CASCADE
SQL directive to the Foreign Key declaration.
Taken this in mind, you can correct your mapping in the following way:
@Entity
@Table(name = "comment_vote")
public class CommentVote {
// ...
@ManyToOne()
@JoinColumn(name="user_id", nullable=false)
@OnDelete(action = OnDeleteAction.CASCADE)
@JsonIgnore
private User user;
// ...
}
What is the difference between CascadeType.REMOVE and orphanRemoval in JPA?
From here:-
Cascading Remove
Marking a reference field with CascadeType.REMOVE (or CascadeType.ALL,
which includes REMOVE) indicates that remove operations should be
cascaded automatically to entity objects that are referenced by that
field (multiple entity objects can be referenced by a collection
field):@Entity
class Employee {
:
@OneToOne(cascade=CascadeType.REMOVE)
private Address address;
:
}
Orphan Removal
JPA 2 supports an additional and more aggressive remove cascading mode
which can be specified using the orphanRemoval element of the
@OneToOne and @OneToMany annotations:@Entity
class Employee {
:
@OneToOne(orphanRemoval=true)
private Address address;
:
}
DIFFERENCE:-
The difference between the two settings is in the response to
disconnecting a relationship. For example, such as when setting the
address field to null or to another Address object.
- If orphanRemoval=true is specified the disconnected Address instance is automatically removed. This is useful for cleaning up
dependent objects (e.g. Address) that should not exist without a
reference from an owner object (e.g. Employee).- If only cascade=CascadeType.REMOVE is specified no automatic action is taken since disconnecting a relationship is not a remove
operation.
JPA CascadeType.REMOVE not working
JPA can only remove and cascade the remove over entities it knows about, and if you have not been maintaining both sides of this bidirectional relationship, issues like this will arise. If the collection of departments is empty, try an em.refresh() before the remove, forcing JPA to populate all relationships so that they can be correctly removed, though it is better to maintain both sides of the relationship as changes are made to avoid the database hit.
Related Topics
Listview Is Blank While Using Getfilter Function
Create a New Textview Programmatically Then Display It Below Another Textview
How to Paginate Queries by Combining Query Cursors Using Firestorerecycleradapter
How to Downsample Images Within PDF File
Is There a Common Java Utility to Break a List into Batches
Java Method to Swap Primitives
Test If Element Is Present Using Selenium Webdriver
Why Does Java Implicitly (Without Cast) Convert a 'Long' to a 'Float'
Why Double Width = 50/110000; the Output Is 0.000000000000000
Android: How to Stretch an Image to the Screen Width While Maintaining Aspect Ratio
Firestore Query - Checking If Username Already Exists
Linux Command for Extracting War File
Why Does Priorityqueue.Tostring Return the Wrong Element Order