Should I let JPA or the database cascade deletions?

安稳与你 提交于 2019-12-20 12:15:42

问题


Let's say we have two entities, A and B. B has a many-to-one relationship to A like follows:

@Entity
public class A {
  @OneToMany(mappedBy="a_id")
  private List<B> children;
}

@Entity
public class B {
  private String data;
}

Now, I want to delete the A object and cascade the deletions to all its children (B). There are two ways to do this:

1) Add cascade=CascadeType.ALL, orphanRemoval=true to the OneToMany annotation, letting JPA remove all children before removing the A-object from the database.

2) Leave the classes as they are and simply let the database cascade the deletion.

Is there any problem with using the later option? Will it cause the Entity Manager to keep references to already deleted objects? My reason for choosing option two over one is that option one generates n+1 SQL queries for a removal, which can take a prolonged time when object A contains a lot of children, while option two only generates a single SQL query and then moves on happily. Is there any "best practice" regarding this?


回答1:


In EclipseLink you can use both if you use the @CascadeOnDelete annotation. EclipseLink will also generate the cascade DDL for you.

See, http://wiki.eclipse.org/EclipseLink/Examples/JPA/DeleteCascade

This optimizes the deletion by letting the database do it, but also maintains the cache and the persistence unit by removing the objects.

Note that orphanRemoval=true will also delete objects removed from the collection, which the database cascade constraint will not do for you, so having the rules in JPA is still necessary. There are also some relationships that the database cannot handle deletion for, as the database can only cascade in the inverse direction of the constraint, a OneToOne with a foreign key, or a OneToMany with a join table cannot be cascaded on the database.




回答2:


I'd prefer the database. Why?

  • The database is probably a lot faster doing this
  • The database should be the primary place to hold integrity and relationship information. JPA is just reflecting that information
  • If you're connecting with a different application / platform (i.e. without JPA), you can still cascadingly delete your records, which helps increase data integrity



回答3:


This answer raises some really strong arguments about why it should be JPA that handles the cascade, not the database.

Here's the relevant quote:

...if you would make cascades on database, and not declare them in Hibernate (for performance issues) you could in some circumstances get errors. This is because Hibernate stores entities in its session cache, so it would not know about database deleting something in cascade.

When you use second-level cache, your situation is even worse, because this cache lives longer than session and such changes on db-side will be invisible to other sessions as long old values are stored in this cache.



来源:https://stackoverflow.com/questions/5787551/should-i-let-jpa-or-the-database-cascade-deletions

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!