Parent Perspective in Entity Mapping
Have you ever asked: “Should the parent own the relation, with cascade all, and the child DTO not even mention the parent?”
That’s often a good and clean approach, and here’s why.
✅ When the Parent Owns the Relation

@Entity
public class Person {
@OneToOne(cascade = CascadeType.ALL, orphanRemoval = true)
@JoinColumn(name = "passport_id")
private Passport passport;
}
Pros:
- Clear lifecycle control: When you persist or delete the parent, the child follows.
- Simpler DTOs: Child DTO doesn’t need a back-reference to parent, reducing nesting.
- Works great when child is tightly coupled to the parent (e.g.,
Passport
can’t exist withoutPerson
).
DTO Example (clean):
public record PersonDto(Long id, String name, PassportDto passport) {}
public record PassportDto(String number, LocalDate issueDate) {}
No need for PersonDto
inside PassportDto
.
✅ When to Use This (and Cascade ALL)
- Child only exists with the parent
- You’re creating/updating data mostly via parent
- You want to reduce back-reference clutter and circular mapping
- You don’t care about child-to-parent navigation (e.g.,
passport.getPerson()
)
⚠️ When the Child Should Keep a Parent Reference

@Entity
public class Passport {
@OneToOne
@JoinColumn(name = "person_id")
private Person person;
}
Use only when:
- Child needs context of parent (e.g., audit, filtering, backrefs)
- You often load children independently and need to reach the parent
- You’re modeling a bidirectional graph for complex navigation
In DTOs, this can lead to recursive structures or unnecessary nesting:
public record PassportDto(String number, LocalDate issueDate, PersonDto person) {}
Which can get ugly, especially in JSON responses.
✅ Recommended Clean Design
Let the parent own the relationship, use cascade + orphan removal, and avoid child-to-parent references unless strictly necessary.
This way:
- Your APIs stay flat and clean.
- Your mappers don’t loop.
- You don’t overfetch or serialize unintended stuff.
Bonus: @JsonIgnore and Mapping
If you must have a bidirectional entity model, you can still keep DTOs clean:
@Entity
public class Passport {
@JsonIgnore
@OneToOne(mappedBy = "passport")
private Person person;
}

A test poc implementation can be found here.