✅ Scenario: Mapping
You have:
@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;
}
📥 Insert Parent + Children
Code:
ParentEntity parent = new ParentEntity();
ChildEntity child1 = new ChildEntity();
ChildEntity child2 = new ChildEntity();
child1.setParent(parent);
child2.setParent(parent);
parent.getChildren().add(child1);
parent.getChildren().add(child2);
session.persist(parent);
SQL executed:
1️⃣ INSERT
parent row:
insert into parent_entity (id, ...) values (1, ...);
2️⃣ INSERT
each child row with foreign key:
insert into child_entity (id, parent_id, ...) values (10, 1, ...);
insert into child_entity (id, parent_id, ...) values (11, 1, ...);
📤 Select Parent + Children
Parent alone:
ParentEntity parent = session.find(ParentEntity.class, 1L);
SQL:
select ... from parent_entity where id=1;
✅ No child data loaded if collection is LAZY → Hibernate will proxy the children.
Accessing children:
parent.getChildren().size(); // triggers child collection loading
SQL:
select ... from child_entity where parent_id=1;
🗑️ Delete Parent
session.remove(parent);
If you have cascade = CascadeType.ALL
+ orphanRemoval = true
, Hibernate issues:
1️⃣ Delete all child rows first:
delete from child_entity where parent_id=1;
2️⃣ Delete parent row:
delete from parent_entity where id=1;
✅ This ensures referential integrity → avoids foreign key constraint violations.
🔄 Remove Child from Parent Collection
parent.getChildren().remove(child1);
If orphanRemoval = true
, Hibernate issues:
delete from child_entity where id=10;
Otherwise (orphanRemoval = false), Hibernate updates the child to detach it:
update child_entity set parent_id=null where id=10;
📝 Update Child
child1.setSomeField("newValue");
Hibernate issues:
update child_entity set some_field='newValue' where id=10;
🕵️ Special Note on Bidirectional Consistency
Hibernate does not issue extra SQL to “sync” Java-side parent-child references.
It’s your responsibility to maintain consistency:
child.setParent(parent);
parent.getChildren().add(child);
📌 Key Takeaways
✅ Insert parent + children → INSERT parent → INSERT children with parent_id
.
✅ Select parent → one SELECT on parent; child collection triggers separate SELECT if accessed (unless using fetch join).
✅ Delete parent → DELETE children (if cascade+orphanRemoval) → DELETE parent.
✅ Remove child from collection → DELETE child or set parent_id=null
depending on orphanRemoval.
✅ Bidirectional mappings require you to sync both sides in Java objects — Hibernate does not auto-sync Java references.