Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the meaning of the CascadeType.ALL for a @ManyToOne JPA association

People also ask

What is CascadeType all in JPA?

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 .

What is CascadeType in Hibernate?

The cascading types supported by the hibernate framework are as follow: CascadeType. PERSIST : It means that the save() and persist() operations in the hibernate cascade to the related entities. CascadeType. MERGE : It means that the related entities are joined when the owning entity is joined.

What is default CascadeType?

CascadeType defaults to the empty array . See CascadeType in Annotation Type OneToOne. By default no operations are cascaded.

What is CascadeType remove?

CascadeType. REMOVE is a way to delete a child entity or entities whenever the deletion of its parent happens.


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.


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.


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


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.


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.


If you just want to delete the address assigned to the user and not to affect on User entity class you should try something like that:

@Entity
public class User {
   @OneToMany(mappedBy = "addressOwner", cascade = CascadeType.ALL)
   protected Set<Address> userAddresses = new HashSet<>();
}

@Entity 
public class Addresses {
   @ManyToOne(cascade = CascadeType.REFRESH) @JoinColumn(name = "user_id")
   protected User addressOwner;
}

This way you dont need to worry about using fetch in annotations. But remember when deleting the User you will also delete connected address to user object.