JPA Relationship Mappings & Querying – Complete Notes

 


JPA Relationship Mappings & Querying – Complete Notes


1. One-to-Many (Unidirectional)

Concept

One parent entity is associated with multiple child entities.

Example:

  • One User → Many Orders

Important Problem

You cannot store multiple child IDs in one row.

So JPA creates a new mapping table by default.

Default Behavior

  • Creates a third table
  • Uses LAZY loading

 


2. One-to-Many Without Extra Table

If you don’t want the extra table, use:

@OneToMany
@JoinColumn(name = "user_id")

Now:

  • Foreign key is stored in child table
  • No extra mapping table

This is most commonly used in real systems.

 


3. Cascade in One-to-Many

Cascade Effect
PERSIST Save parent → save children
MERGE Update parent → update children
REMOVE Delete parent → delete children
ALL All above

 


4. Orphan Removal

If child removed from list:

user.getOrders().remove(order);

With:

orphanRemoval = true

Hibernate deletes that child row automatically.

Very useful for:

  • Cart items
  • Attachments
  • User addresses

 


5. Bidirectional One-to-Many

Both sides know each other.

User → List<Order>
Order → User

Owning Side

  • Child (holds FK)

Inverse Side

  • Parent (only object reference)

 


6. Many-to-One (Unidirectional)

Most common relationship in real apps.

Example:

  • Many Orders → One User

Only child has reference.

@ManyToOne
private User user;

Parent doesn’t know children.

 


7. Many-to-Many

Example:

  • Many Students ↔ Many Courses

Default

Creates a join table.

student_course

Can be:

  • Unidirectional
  • Bidirectional

Anyone can be owning side.

 


DERIVED QUERIES (Spring Data JPA Magic)


8. What is Derived Query?

Spring automatically creates SQL from method names.

findUserDetailsByName(String name);

Generates:

SELECT * FROM user_details WHERE name = ?

No SQL written by you.

 


9. Naming Rule (Internal Engine)

Method must start with:

find | read | get | query | search | count | exists | delete

And end with By

This is parsed by PartTree.java.

 


10. Logical Operators

AND

findByNameAndPhone()

OR

findByNameOrPhone()

LIKE

findByNameLike()

IN

findByNameIn(List<String>)

Hibernate generates proper SQL automatically.

 


11. Pagination

Two interfaces:

Pageable
Sort

Example:

PageRequest.of(0, 5)

Means:

  • Page 0
  • 5 records

 


12. Page Object

If return type is:

Page<User>

You get:

  • totalPages
  • isFirst
  • isLast
  • totalElements

Useful for frontend pagination.

 


JPQL (Java Persistence Query Language)


13. Why JPQL?

When queries become complex.

Works on:

  • Entity names
  • Java fields

Not DB table names.

Database independent.

 


14. JPQL Example

@Query("SELECT u FROM UserDetails u WHERE u.name = :name")

Rules:

  • Uses entity name
  • Uses field name
  • Not column name

 


15. @Modifying

Used when query is:

  • DELETE
  • UPDATE
  • INSERT
@Modifying
@Transactional

Otherwise JPA throws error.

 


N+1 PROBLEM (Real Performance Killer)


16. What is N+1?

Scenario:

  • 1 User has many addresses
  • Fetch 10 users

Queries:
1 query → fetch users
10 queries → fetch addresses

Total = 11 queries

This kills performance.

 


17. Why EAGER Doesn’t Fix It?

EAGER works only when:

  • Fetching single parent

Fails when:

  • Multiple parents
  • Multiple children

Still produces N+1 queries.

 


18. Solutions to N+1

Solution 1: JOIN FETCH (Best)

@Query("SELECT u FROM User u JOIN FETCH u.addresses")

One SQL query only.


Solution 2: @BatchSize

Loads children in batches:

@BatchSize(size = 10)

Reduces queries.


Solution 3: @EntityGraph

@EntityGraph(attributePaths = "addresses")

Works even in derived queries.

 


FLUSH & CLEAR


19. Flush

Pushes in-memory data to DB
But keeps it in memory.


20. Clear

Deletes persistence context.
Next read → hits DB again.

Used in:

  • Batch jobs
  • Memory optimization

 


Real Industry Best Practices

These are actual rules followed in companies:

  1. Always use DTO in APIs
  2. Never return Entity directly
  3. Avoid CascadeType.ALL
  4. Use LAZY + JOIN FETCH
  5. Solve N+1 before production
  6. Prefer ManyToOne over OneToMany
  7. Use JPQL for complex queries
  8. Always use Pageable for large data

Interview One-Liners

You can literally say:

  • “Derived queries are parsed using PartTree.”
  • “JPQL works on entities, not tables.”
  • “N+1 occurs due to lazy loading of collections.”
  • “JOIN FETCH is the best fix for N+1.”
  • “Orphan removal ensures referential integrity.”
  • “Flush pushes, clear purges.”

 

Leave a Reply