Open In App

JPA – Cascade Persist

Last Updated : 08 Apr, 2024
Improve
Improve
Like Article
Like
Save
Share
Report

In Java, JPA is defined as the Java Persistence API and acts as a bridge between Java objects and a relational database. It simplifies simple data management in Java applications. One of the key features of the JPA is Cascade Persist and it is a mechanism designed to sustain the relevant companies once the parent company becomes sustainable

Cascade Persist in JPA

Cascade Persist in JPA provides persistent relationship handling by automatically propagating changes from parent entities to their associated child entities. When an entity is specified with CascadeType.PERSIST, any persistent action to be performed on a parent entity to its affiliates, and also ensures sustainability, increases flexibility and maintainability.

Implementation Steps:

1. Define the Entity Relationships

It can begin by establishing the relationships between the entities using JPA annotations such as the @OneToOne, @OneToMany, or @ManyToOne. These annotations define the nature of the relationship between the entities. It can specifying whether it is the one-to-one, one-to-many or many-to-one.

Example:

Parent Entity


@Entity
public class Parent {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;

private String name;

@OneToMany(mappedBy = "parent", cascade = CascadeType.PERSIST)
private List<Child> children = new ArrayList<>();

// Getters and Setters
}

Child Entity:

@Entity
public class Child {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;

private String name;

@ManyToOne
private Parent parent;

// Getters and Setters
}

2. Configure the Cascade Persist

It can enable the cascade persist behavior and annotate the relationship field in the parent entity with the CascadeType.PERSIST. It informs the persistence context that any persistence operation performed on the parent entity should cascade to its the associated with child entities.

Example:

// Parent Entity
@Entity
public class Parent {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;

private String name;

@OneToMany(mappedBy = "parent", cascade = CascadeType.PERSIST)
private List<Child> children = new ArrayList<>();

// Getters and Setters
}

3. Persist Parent Entity

It can utilize the EntityManager.persist() to the persist the parent entity within the persistence context. As the result of the cascade persist configuration, any associated with child entities will also be persisted automatically without the explicit calls to EntityManager.persist() for each child entity.

EntityManager em = entityManagerFactory.createEntityManager();
em.getTransaction().begin();

Parent parent = new Parent();
// Set parent properties

Child child = new Child();
// Set child properties
child.setParent(parent); // Associate child with parent

parent.getChildren().add(child); // Add child to parent's list of children

em.persist(parent); // Persist parent entity (Cascade Persist will save child entities)

em.getTransaction().commit();
em.close();

4. Verify the Persistence

It can confirm the successful persistence of the both parent and associated with child entities by the retrieving them from the database using the EntityManager.find(). This step can validates that cascade persist functionality is functioning as expected. It can ensuring the data integrity within the database.

Example:

EntityManager em = entityManagerFactory.createEntityManager();
Parent persistedParent = em.find(Parent.class, parentId);
// Verify persistence of parent entity and associated child entities
System.out.println("Persisted Parent: " + persistedParent.getName());
System.out.println("Persisted Children: " + persistedParent.getChildren().size());
em.close();

Key Components:

  • CascadeType Options: Besides the CascadeType.PERSIST, JPA can provides the other cascade options like the MERGE, REMOVE, REFRESH and ALL. It can offering the flexibility in the managing the entity state transitions.
  • Different Cascades in Different Relationships: Cascade behavior can vary in one-to-one, one-to-many, many-to-one-to-many-to-many relationships and can affect how it changes the breadth of exposure a it combines between
  • Handling cascade operations: Developers may need to be careful when implementing cascade operations to avoid unintended side effects such as orphans or duplicate projects
  • JPA Lifecycle Events: Understanding the JPA entity lifecycle events such as @PrePersist, @PostPersist and it can helps in the customizing the customizing cascade behavior and the executing additional logic during the entity state transitions.

Project to demonstrate the Implementation of JPA – Cascade Persist

Below are the steps to demonstrate the implementation of JPA – Cascade Persist.

Step 1: Create the new JPA project using the Intellj Idea named as jpa-cascade-persist-demo.

Step 2: Open the pom.xml and add the below dependencies into the project.

Dependencies:

<dependency>
<groupId>org.hibernate.orm</groupId>
<artifactId>hibernate-core</artifactId>
<version>6.0.2.Final</version>
</dependency>
<dependency>
<groupId>org.glassfish.jaxb</groupId>
<artifactId>jaxb-runtime</artifactId>
<version>3.0.2</version>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-api</artifactId>
<version>${junit.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-engine</artifactId>
<version>${junit.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.28</version>
</dependency>

Once the project has created successfully, the file structure will look like the below image.

File Structure


Step 3: Open the persistence.xml and put the below code into the project and it can configure the database of the project.

XML
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<persistence xmlns="https://jakarta.ee/xml/ns/persistence"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="https://jakarta.ee/xml/ns/persistence https://jakarta.ee/xml/ns/persistence/persistence_3_0.xsd"
             version="3.0">
    <persistence-unit name="default">
        <class>model.Parent</class>
        <class>model.Child</class>
        <properties>
            <property name="javax.persistence.jdbc.url" value="jdbc:mysql://localhost:3306/example"/>
            <property name="javax.persistence.jdbc.user" value="root"/>
            <property name="javax.persistence.jdbc.password" value=""/>
            <property name="javax.persistence.jdbc.driver" value="com.mysql.jdbc.Driver"/>
            <property name="hibernate.dialect" value="org.hibernate.dialect.MySQL5Dialect"/>
            <property name="hibernate.hbm2ddl.auto" value="update"/>
        </properties>

    </persistence-unit>
</persistence>


Step 4: Create a new Java package named as model and in that package, create an Entity Java class named as the Parent.

Go to src > main > java > model > Parent and put the below code.

Java
package model;

import jakarta.persistence.*;

import java.util.ArrayList;
import java.util.List;

@Entity
public class Parent {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    private String name;

    @OneToMany(mappedBy = "parent", cascade = CascadeType.PERSIST)
    private List<Child> children = new ArrayList<>();

    // Getters and Setters

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public List<Child> getChildren() {
        return children;
    }

    public void setChildren(List<Child> children) {
        this.children = children;
    }
}


Step 5: In model package, create a new Entity Java class named as the Child .

Go to src > main > java > model > Child and put the below code.

Java
package model;

import jakarta.persistence.*;


@Entity
public class Child {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    private String name;

    @ManyToOne
    private Parent parent;

    // Getters and Setters
    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Parent getParent() {
        return parent;
    }

    public void setParent(Parent parent) {
        this.parent = parent;
    }
}


Step 6: Create a new Java class named as the MainApplication.

Go to src > main > java > MainApplication and put the below code.

Java
import jakarta.persistence.EntityManager;
import jakarta.persistence.EntityManagerFactory;
import jakarta.persistence.Persistence;
import model.Child;
import model.Parent;

public class MainApplication {
    public static void main(String[] args) {
        EntityManagerFactory emf = Persistence.createEntityManagerFactory("default");
        EntityManager em = emf.createEntityManager();

        // Create parent entity with associated child entities
        Parent parent = new Parent();
        parent.setName("Parent");

        Child child1 = new Child();
        child1.setName("Child 1");
        child1.setParent(parent);

        Child child2 = new Child();
        child2.setName("Child 2");
        child2.setParent(parent);

        parent.getChildren().add(child1);
        parent.getChildren().add(child2);

        // Persist parent entity (Cascade Persist will save child entities)
        em.getTransaction().begin();
        em.persist(parent);
        em.getTransaction().commit();

        // Verify Persistence
        Parent persistedParent = em.find(Parent.class, parent.getId());
        System.out.println("Persisted Parent: " + persistedParent.getName());
        System.out.println("Persisted Children: " + persistedParent.getChildren().size());

        em.close();
        emf.close();
    }
}
  • The MainApplication class demonstrates the use of Cascade Persist in JPA by persisting a parent entity along with its associated child entities.
  • It creates a parent entity with two child entities, sets up the parent-child relationship, and then persists the parent entity.
  • The cascade persist behavior automatically saves the child entities as well.
  • Finally, it verifies the persistence by retrieving the parent entity from the database and printing its name along with the number of associated child entities.

pom.xml:

XML
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>org.example</groupId>
    <artifactId>jpa-Cascade-Persist-demo</artifactId>
    <version>1.0-SNAPSHOT</version>
    <name>jpa-Cascade-Persist-demo</name>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <maven.compiler.target>11</maven.compiler.target>
        <maven.compiler.source>11</maven.compiler.source>
        <junit.version>5.9.2</junit.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.hibernate.orm</groupId>
            <artifactId>hibernate-core</artifactId>
            <version>6.0.2.Final</version>
        </dependency>
        <dependency>
            <groupId>org.glassfish.jaxb</groupId>
            <artifactId>jaxb-runtime</artifactId>
            <version>3.0.2</version>
        </dependency>
        <dependency>
            <groupId>org.junit.jupiter</groupId>
            <artifactId>junit-jupiter-api</artifactId>
            <version>${junit.version}</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.junit.jupiter</groupId>
            <artifactId>junit-jupiter-engine</artifactId>
            <version>${junit.version}</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>8.0.28</version>
        </dependency>
    </dependencies>

    <build>
        <plugins>
        </plugins>
    </build>
</project>


Step 7: Once the project is completed, run the application. It will show the parent and child count as output. Refer the below image for the better understanding of the concept.

Output Screen

By the carefully configuring cascade options and handling the cascade operations, the developers can ensure the data integrity and consistency within the database.



Like Article
Suggest improvement
Share your thoughts in the comments

Similar Reads