Hibernate Tutorial

Core Hibernate

Hibernate Mapping

Hibernate Annotations

Hibernate with Spring Framework

Hibernate with Database

Hibernate Log4j

Inheritance Mapping

Hibernate - Different Cascade Types

In Hibernate, cascading is a convenient feature that lets an operation on an entity be propagated or cascaded to its associated entities. This is very useful when you have parent-child relationships and you want certain operations on the parent to affect the children.

Hibernate provides various cascade types that you can use based on your requirements. Let's take a look at them:

Different Cascade Types in Hibernate:

1. CascadeType.PERSIST:

  • Description: When persisting an entity, also persist the entities held in this particular relationship. It doesn't affect other operations like remove or merge.

  • Example: If you have an Order entity and an OrderLine entity and you save the Order entity, the related OrderLine entities will also get saved if the relationship is set to CascadeType.PERSIST.

2. CascadeType.MERGE:

  • Description: When merging changes of a detached entity, also merge the entities held in this relationship.

  • Example: If you modify a detached Order entity and then merge it, the changes will also be merged for the related OrderLine entities if the relationship is set to CascadeType.MERGE.

3. CascadeType.REMOVE:

  • Description: When deleting an entity, also delete the entities held in this relationship.

  • Example: If you delete an Order entity, the related OrderLine entities will also get deleted if the relationship is set to CascadeType.REMOVE.

4. CascadeType.REFRESH:

  • Description: When refreshing an entity state, also refresh the entities held in this particular relationship.

  • Example: If you refresh an Order entity, the related OrderLine entities will also get refreshed if the relationship is set to CascadeType.REFRESH.

5. CascadeType.DETACH:

  • Description: If an entity gets detached, the related entities will also get detached.

  • Example: If you detach an Order entity, the related OrderLine entities will also get detached if the relationship is set to CascadeType.DETACH.

6. CascadeType.ALL:

  • Description: This cascades all the above types (PERSIST, MERGE, REMOVE, REFRESH, DETACH). Use this if an operation should propagate all the cascade types to the related entities.

  • Example: If you set Order and OrderLine relationship to CascadeType.ALL, any of the operations (persist, merge, remove, refresh, detach) performed on Order will also be cascaded to OrderLine.

Mapping Example:

To specify cascade types in Hibernate mapping, you can use annotations:

@Entity
public class Order {
    @OneToMany(cascade = CascadeType.ALL)
    private List<OrderLine> orderLines;
    // ...
}

In the above example, any operation on Order will cascade to the related OrderLine entities.

Conclusion:

When deciding on the cascade type, it's essential to understand the business requirements and the implications of cascading operations, especially with respect to database operations and performance. Overusing cascading, especially CascadeType.REMOVE and CascadeType.ALL, can lead to unintended data loss if not used judiciously.

  1. Configuring cascade types in Hibernate associations:

    • Description: Cascade types are configured in the association annotations (e.g., @OneToMany, @ManyToMany). This determines which operations on the owning entity should be cascaded to the associated entities.
    • Code:
      @Entity
      public class ParentEntity {
          @OneToMany(mappedBy = "parent", cascade = CascadeType.ALL)
          private List<ChildEntity> children = new ArrayList<>();
      }
      
  2. Handling orphan removal with cascade types in Hibernate:

    • Description: Orphan removal removes child entities when they are no longer referenced by the owning entity. It is controlled by the orphanRemoval attribute in the @OneToMany or @OneToOne annotations.
    • Code:
      @Entity
      public class ParentEntity {
          @OneToMany(mappedBy = "parent", cascade = CascadeType.ALL, orphanRemoval = true)
          private List<ChildEntity> children = new ArrayList<>();
      }