What is the meaning of the CascadeType.ALL for a @ManyToOne JPA association
Solution 1:
The meaning of CascadeType.ALL
is that the persistence will propagate (cascade) all EntityManager
operations (PERSIST, REMOVE, REFRESH, MERGE, DETACH
) to the relating entities.
It seems in your case to be a bad idea, as removing an Address
would lead to removing the related User
. As a user can have multiple addresses, the other addresses would become orphans. However the inverse case (annotating the User
) would make sense - if an address belongs to a single user only, it is safe to propagate the removal of all addresses belonging to a user if this user is deleted.
BTW: you may want to add a mappedBy="addressOwner"
attribute to your User
to signal to the persistence provider that the join column should be in the ADDRESS table.
Solution 2:
You shouldn't use CascadeType.ALL
on @ManyToOne
since entity state transitions should propagate from parent entities to child ones, not the other way around.
The @ManyToOne
side is always the Child association since it maps the underlying Foreign Key column.
Therefore, you should move the CascadeType.ALL
from the @ManyToOne
association to the @OneToMany
side, which should also use the mappedBy
attribute since it's the most efficient one-to-many table relationship mapping.
Solution 3:
See here for an example from the OpenJPA docs. CascadeType.ALL
means it will do all actions.
Quote:
CascadeType.PERSIST: When persisting an entity, also persist the entities held in its fields. We suggest a liberal application of this cascade rule, because if the EntityManager finds a field that references a new entity during the flush, and the field does not use CascadeType.PERSIST, it is an error.
CascadeType.REMOVE: When deleting an entity, it also deletes the entities held in this field.
CascadeType.REFRESH: When refreshing an entity, also refresh the entities held in this field.
CascadeType.MERGE: When merging entity state, also merge the entities held in this field.
Sebastian
Solution 4:
From the EJB3.0 Specification:
Use of the cascade annotation element may be used to propagate the effect of an operation to associated entities. The cascade functionality is most typically used in parent-child relationships.
If X is a managed entity, the remove operation causes it to become removed. The remove operation is cascaded to entities referenced by X, if the relationships from X to these other entities is annotated with the cascade=REMOVE or cascade=ALL annotation element value.
So in a nutshell, entity relationships defined with CascadeType.All
will ensure that all persistence events such as persist, refresh, merge and remove that occur on the parent, will be passed to the child. Defining other CascadeType
options provides the developer with a more granular level of control over how the entity association handles persistence.
For example if I had an object Book that contained a List of pages and I add a page object within this list. If the @OneToMany
annotation defining the association between Book and Page is marked as CascadeType.All
, persisting the Book would result in the Page also being persisted to the database.
Solution 5:
In JPA 2.0 if you want to delete an address if you removed it from a User entity you can add orphanRemoval=true
(instead of CascadeType.REMOVE
) to your @OneToMany
.
More explanation between orphanRemoval=true
and CascadeType.REMOVE
is here.