When Hibernate (or another JPA implementation) creates foreign key for @OneToMany relationship, is there a way to force it to use ON DELETE CASCADE at the database level? I found that when I use CascadeType.DELETE, Hibernate doesn't do it at the database level, but sends two delete statements (for parent and child records) instead. Or maybe there's a good reason for that?
问题:
回答1:
In hibernate, you can use
@OnDelete(action = OnDeleteAction.CASCADE)
on your @OneToMany relationship. This tells hibernate to set ON DELETE CASCADE for the generated foreign key.
Note that this is a hibernate extension and is not specified in the JPA standard.
Use this with caution. When you let database cascade the deletes, these happen outside the control of hibernate so:
- Your second-level cache might become out of sync.
- You cant use on delete listeners on those entities.
I think you should only use this if you have a large collection and performance consideration forces you to let database handles the delete instead of hibernate.
回答2:
They aren't the same thing. JPA Cascade traverses DOWN the object graph whereas database foreign key actions effectively traverse UP the object graph. For example let's say you have a one-to-one directional relationship
class House {
@OneToOne
Object door;
}
If you use CascadeType.REMOVE then deleting the house will also delete the door.
@OneToOne(cascade=CascadeType.REMOVE)
Object door;
If you use @OnDelete then deleting the door will also delete the house.
@OneToOne
@OnDelete(action = OnDeleteAction.CASCADE)
Object door;
Read more here: http://www.ninthavenue.com.au/jpa-cascadetype-remove-vs-hibernate-ondelete