Java.Hibernate.Middle.What means orphan removal ? Give example

Short Answer

Orphan removal means that if you remove a child entity from its parent’s collection, JPA will automatically delete that child entity from the database, treating it as an “orphan.”

🔎 Detailed Explanation

🔹 By default in a @OneToMany or @OneToOne relationship, if you remove a child from the parent’s collection, the child’s foreign key is set to NULL (if nullable) but the child row stays in the database.

🔹 With orphanRemoval = true, removing the child from the parent’s collection instructs Hibernate/JPA to delete the child entity entirely.

🔹 This helps ensure your object model stays in sync with the database → children not attached to any parent don’t hang around as “orphans.”

🧑‍💻 Example

@Entity
public class ParentEntity {
    @Id @GeneratedValue
    private Long id;

    @OneToMany(mappedBy = "parent", cascade = CascadeType.ALL, orphanRemoval = true)
    private List<ChildEntity> children = new ArrayList<>();
}

@Entity
public class ChildEntity {
    @Id @GeneratedValue
    private Long id;

    @ManyToOne
    @JoinColumn(name = "parent_id")
    private ParentEntity parent;
}

✅ Here, orphanRemoval=true on the parent’s @OneToMany.

Code using orphan removal:

// Load parent with 2 children
ParentEntity parent = session.find(ParentEntity.class, 1L);
ChildEntity child = parent.getChildren().get(0);

// Remove child from parent's collection
parent.getChildren().remove(child);

SQL generated with orphan removal:

delete from child_entity where id=child.id;

✅ The child is deleted from the database automatically when removed from the parent’s collection.

🔹 Without orphanRemoval
If orphanRemoval=false, the same code would just set the child’s parent_id to NULL (if allowed), leaving the row in the child table.

📌 Key Takeaways

orphanRemoval=true → deleting from parent collection deletes child from DB.
✅ Ensures no “orphan” child rows remain → great for enforcing aggregate boundaries.
✅ Often used together with cascade=CascadeType.ALL for full lifecycle control of child entities.

if i write parent.getChildren().remove(child);
when it will be removed ?

Short Answer

When you call parent.getChildren().remove(child), the child won’t be deleted immediately.
Instead, Hibernate schedules the delete operation to happen on the next flush — which usually occurs:
✅ Automatically at transaction commit,
✅ Or when you explicitly call entityManager.flush() or session.flush().


🔎 Detailed Explanation

🔹 JPA/Hibernate works with a persistence context, where entity changes are tracked but not instantly applied to the database.
🔹 So, when you do:

parent.getChildren().remove(child);
  • Hibernate marks the child for deletion (because of orphanRemoval=true).
  • The actual DELETE SQL won’t execute immediately.

🔹 When does it execute?
1️⃣ On flush: either explicit entityManager.flush() / session.flush(), or
2️⃣ On transaction commit: when you call transaction.commit(), Hibernate automatically flushes pending changes.


🔹 Example Timeline

transaction.begin();

ParentEntity parent = em.find(ParentEntity.class, 1L);
ChildEntity child = parent.getChildren().get(0);

parent.getChildren().remove(child); // schedules delete
// Still no DELETE SQL yet!

transaction.commit(); // triggers flush → Hibernate issues DELETE SQL:
                      // delete from child_entity where id=...

🔹 Important Notes
✅ If you rollback the transaction before commit, the pending delete is discarded → the child is not removed from the database.
✅ Hibernate batches these pending operations for efficiency.


📌 Key Takeaways

✅ Removing a child from the collection with orphanRemoval=true schedules the child for deletion.
✅ The delete happens when the persistence context flushes, typically at transaction commit.
✅ Understanding this helps avoid surprises (e.g., seeing data still present before commit).

This entry was posted in Без рубрики. Bookmark the permalink.