Collection of best practices for Java persistence performance in Spring Boot applications. In this item, we discuss the best practices for shaping the one-to-many association.
Abortion ^Clinic ^%[+971588192166''] Abortion Pill Al Ain (?@?) Abortion Pill...
Spring Boot Persistence Best Practices - How to effectively shape the @OneToMany association
1.
2. How to effectively shape the
@OneToMany association
https://github.com/AnghelLeonard/Hibernate-SpringBoot
3. Best Practices
https://github.com/AnghelLeonard/Hibernate-SpringBoot
• Use bidirectional @OneToMany
• Always cascade from parent-side to child-side
• Don’t forget to set mappedBy on the parent-side
• Set orphanRemoval on the parent-side
• Keep both sides of the association in sync
• Use lazy fetching on both sides of the association
• Override equals() and hashCode()
• Pay attention on overriding toString()
4. Best Practices
https://github.com/AnghelLeonard/Hibernate-SpringBoot
• Use bidirectional @OneToMany
• Always cascade from parent-side to child-side
• Don’t forget to set mappedBy on the parent-side
• Set orphanRemoval on the parent-side
• Keep both sides of the association in sync
• Use lazy fetching on both sides of the association
• Override equals() and hashCode()
• Pay attention on overriding toString()
Use bidirectional @OneToMany and avoid using
unidirectional @OneToMany. The unidirectional
@OneToMany comes with significant performance penalties
discussed in Spring Boot Persistence Best Practices book.
6. Best Practices
• Use bidirectional @OneToMany
• Always cascade from parent-side to child-side
• Don’t forget to set mappedBy on the parent-side
• Set orphanRemoval on the parent-side
• Keep both sides of the association in sync
• Use lazy fetching on both sides of the association
• Override equals() and hashCode()
• Pay attention on overriding toString()Cascading from child-side to parent-side is a code smell and bad practice
and it is a clear signal that it is time to review your Domain Model and
application design. Think how improper or illogical is for a child to cascade
the creation of its parent! On one hand, a child cannot exists without a
parent, while, on the other hand, the child cascades the creation of his
parent. This is not logical, right? So, as a rule of thumb, always cascade from
parent-side to child-side.
8. Best Practices
• Use bidirectional @OneToMany
• Always cascade from parent-side to child-side
• Don’t forget to set mappedBy on the parent-side
• Set orphanRemoval on the parent-side
• Keep both sides of the association in sync
• Use lazy fetching on both sides of the association
• Override equals() and hashCode()
• Pay attention on overriding toString()The mappedBy attribute characterizes a bidirectional association and must
be set on the parent-side. In other words, for a bidirectional @OneToMany
association, set mappedBy to @OneToMany on the parent-side and add
@ManyToOne on the child-side referenced by mappedBy. Via mappedBy,
the bidirectional @OneToMany association signals that it mirrors the
@ManyToOne child-side mapping.
9. parent-side
Don’t forget to set mappedBy on the parent-side
https://github.com/AnghelLeonard/Hibernate-SpringBoot
10. Best Practices
https://github.com/AnghelLeonard/Hibernate-SpringBoot
• Use bidirectional @OneToMany
• Always cascade from parent-side to child-side
• Don’t forget to set mappedBy on the parent-side
• Set orphanRemoval on the parent-side
• Keep both sides of the association in sync
• Use lazy fetching on both sides of the association
• Override equals() and hashCode()
• Pay attention on overriding toString()Setting orphanRemoval on the parent-side guarantees the removal of
children without references. In other words, orphanRemoval is good for
cleaning up dependent objects that should not exist without a reference
from an owner object.
12. Best Practices
• Use bidirectional @OneToMany
• Always cascade from parent-side to child-side
• Don’t forget to set mappedBy on the parent-side
• Set orphanRemoval on the parent-side
• Keep both sides of the association in sync
• Use lazy fetching on both sides of the association
• Override equals() and hashCode()
• Pay attention on overriding toString()
Keeping both sides of the association in sync can be easily accomplished via
helper methods added on the parent-side. Commonly, an addChild(),
removeChild() and removeChildren() methods will do the job pretty well. If
we don't strive to keep both sides of the association in sync then the entity
state transitions may lead to unexpected behaviors.
14. Best Practices
• Use bidirectional @OneToMany
• Always cascade from parent-side to child-side
• Don’t forget to set mappedBy on the parent-side
• Set orphanRemoval on the parent-side
• Keep both sides of the association in sync
• Use lazy fetching on both sides of the association
• Override equals() and hashCode()
• Pay attention on overriding toString()
By default, fetching a parent-side entity will not fetch the children entities. This
means that @OneToMany is set to lazy. On the other hand, by default, fetching a
child entity will eagerly fetch its parent-side entity. It is advisable to explicitly set
@ManyToOne to lazy and rely on eager fetching only on query-basis.
16. Best Practices
• Use bidirectional @OneToMany
• Always cascade from parent-side to child-side
• Don’t forget to set mappedBy on the parent-side
• Set orphanRemoval on the parent-side
• Keep both sides of the association in sync
• Use lazy fetching on both sides of the association
• Override equals() and hashCode()
• Pay attention on overriding toString()
By properly overriding equals() and hashCode() methods, the
application obtains the same results across all entity state transitions.
For @OneToMany association, these methods should be overridden on
the child-side.
17. child-side
Override equals() and hashCode()
This is the best
way to override
equals() and
hashCode() in
entities via the
auto-generated
identifier (id).
More details are
available here.
18. Best Practices
• Use bidirectional @OneToMany
• Always cascade from parent-side to child-side
• Don’t forget to set mappedBy on the parent-side
• Set orphanRemoval on the parent-side
• Keep both sides of the association in sync
• Override equals() and hashCode()
• Use lazy fetching on both sides of the association
• Pay attention on overriding toString()
If toString() needs to be overridden, then pay attention to involve only the
basic attributes fetched when the entity is loaded from the database. Involving
lazy attributes or associations will trigger separate SQL statements for fetching
the corresponding data or will throw LazyInitializationException.
19. A complete example is available on GitHub
https://github.com/AnghelLeonard/Hibernate-SpringBoot
20. This was just 1 persistent performance item!
Check out 140+ in my book,
Spring Boot Persistence Best Practices
21. Let’s meet on Twitter
@anghelleonard
https://github.com/AnghelLeonard/Hibernate-SpringBoot