Розділ 16 · 30 питань

Hibernate JPA

30 питань і відповідей у розділі Hibernate JPA.

Ukrainian Hibernate JPA Вихідний Markdown
Мовні версії: English Russian Ukrainian

Питання цього розділу

  1. Що таке проблема N+1 і як її вирішити
  2. У чому різниця між Lazy та Eager завантаженням
  3. Коли використовувати Lazy, а коли Eager loading
  4. Що таке LazyInitializationException і як її уникнути
  5. Які стратегії fetch існують в Hibernate
  6. Що робить анотація @BatchSize
  7. Опишіть життєвий цикл Entity в Hibernate
  8. Що таке стани transient, persistent, detached, removed
  9. Що таке кеш першого рівня в Hibernate
  10. Що таке кеш другого рівня і коли його використовувати
  11. Як налаштувати кеш другого рівня
  12. Що таке dirty checking в Hibernate
  13. Як працює механізм flush в Hibernate
  14. У чому різниця між persist() і merge()
  15. Що робить метод refresh()
  16. Що таке EntityManager і чим він відрізняється від Session
  17. Як реалізувати оптимістичне блокування в JPA
  18. Як реалізувати песимістичне блокування в JPA
  19. Що таке @Version і навіщо вона потрібна
  20. Як працюють каскадні операції (Cascade)
  21. Які типи Cascade існують
  22. Що таке orphan removal
  23. Як правильно використовувати @OneToMany і @ManyToOne
  24. У чому особливості bidirectional relationships
  25. Як уникнути нескінченної рекурсії при серіалізації Entity
  26. Що таке JPQL і чим він відрізняється від SQL
  27. Що таке Criteria API і коли його використовувати
  28. Як використовувати JOIN FETCH для вирішення проблеми N+1
  29. Що таке projection в JPA
  30. Які типи наслідування підтримує JPA

Навігатор по розділу

30 запитань для підготовки до співбесіди на Middle Java Developer.


📋 Всі запитання

# Запитання Рівень складності
1 Що таке проблема N+1 і як її вирішити ⭐⭐⭐
2 У чому різниця між Lazy та Eager завантаженням ⭐⭐
3 Коли використовувати Lazy, а коли Eager loading ⭐⭐
4 Що таке LazyInitializationException і як її уникнути ⭐⭐
5 Які стратегії fetch існують в Hibernate ⭐⭐⭐
6 Що робить анотація @BatchSize ⭐⭐
7 Опишіть життєвий цикл Entity в Hibernate ⭐⭐⭐
8 Що таке стани transient, persistent, detached, removed ⭐⭐
9 Що таке кеш першого рівня в Hibernate ⭐⭐
10 Що таке кеш другого рівня і коли його використовувати ⭐⭐⭐
11 Як налаштувати кеш другого рівня ⭐⭐⭐
12 Що таке dirty checking в Hibernate ⭐⭐⭐
13 Як працює механізм flush в Hibernate ⭐⭐⭐
14 У чому різниця між persist() і merge() ⭐⭐
15 Що робить метод refresh() ⭐⭐
16 Що таке EntityManager і чим він відрізняється від Session ⭐⭐
17 Як реалізувати оптимістичне блокування в JPA ⭐⭐
18 Як реалізувати песимістичне блокування в JPA ⭐⭐⭐
19 Що таке @Version і навіщо вона потрібна ⭐⭐
20 Як працюють каскадні операції (Cascade) ⭐⭐
21 Які типи Cascade існують ⭐⭐
22 Що таке orphan removal ⭐⭐
23 Як правильно використовувати @OneToMany і @ManyToOne ⭐⭐⭐
24 У чому особливості bidirectional relationships ⭐⭐⭐
25 Як уникнути нескінченної рекурсії при серіалізації Entity ⭐⭐
26 Що таке JPQL і чим він відрізняється від SQL ⭐⭐
27 Що таке Criteria API і коли його використовувати ⭐⭐⭐
28 Як використовувати JOIN FETCH для вирішення проблеми N+1 ⭐⭐⭐
29 Що таке projection в JPA ⭐⭐
30 Які типи наслідування підтримує JPA ⭐⭐⭐

🗺️ Карта залежностей тем

                    ┌──────────────────────────────────────────┐
                    │   FETCH І N+1 (1-6)                      │
                    │   1. N+1 проблема                        │
                    │   2. Lazy vs Eager                       │
                    │   3. Коли що обрати                      │
                    │   4. LazyInitializationException         │
                    │   5. Fetch стратегії                     │
                    │   6. @BatchSize                          │
                    └──────────────────┬───────────────────────┘
                                       │
            ┌──────────────────────────┼──────────────────────────┐
            ▼                          ▼                          ▼
    ┌───────────────┐        ┌───────────────┐        ┌────────────────────┐
    │ ENTITY         │        │ CACHING       │        │ LOCKING            │
    │ LIFECYCLE      │        │ (9-13)        │        │ (17-19)            │
    │ (7-8, 12-16)   │        │ 9. L1 cache   │        │ 17. Optimistic     │
    │ 7. Lifecycle   │        │ 10. L2 cache  │        │ 18. Pessimistic    │
    │ 8. Stani       │        │ 11. L2 налашт.│        │ 19. @Version       │
    │ 12. Dirty chk  │        │ 12. Dirty chk │        │                    │
    │ 13. Flush      │        │ 13. Flush     │        │                    │
    │ 14. persist/   │        │               │        │                    │
    │     merge      │        │               │        │                    │
    │ 15. refresh    │        │               │        │                    │
    │ 16. EM vs Sess │        │               │        │                    │
    └───────┬───────┘        └───────┬───────┘        └────────┬───────────┘
            │                        │                        │
            └────────────────────────┼────────────────────────┘
                                     ▼
                    ┌──────────────────────────────────────────┐
                    │   RELATIONSHIPS (20-25)                  │
                    │   20. Cascade огляд                      │
                    │   21. Cascade типи                       │
                    │   22. Orphan removal                     │
                    │   23. @OneToMany/@ManyToOne              │
                    │   24. Bidirectional                      │
                    │   25. Серіалізація рекурсії              │
                    └──────────────────────────────────────────┘
                                     │
            ┌────────────────────────┼────────────────────────┐
            ▼                        ▼                        ▼
    ┌───────────────┐        ┌───────────────┐        ┌────────────────────┐
    │ QUERY LANG     │        │ N+1 РІШЕННЯ    │        │ НАСЛІДУВАННЯ       │
    │ (26-27)        │        │ (28-29)        │        │ (30)               │
    │ 26. JPQL vs    │        │ 28. JOIN FETCH │        │ 30. Inheritance    │
    │    SQL         │        │ 29. Projection │        │    types           │
    │ 27. Criteria   │        │                │        │                    │
    │    API         │        │                │        │                    │
    └───────────────┘        └───────────────┘        └────────────────────┘

🎯 Рекомендований порядок вивчення

🟢 Рівень Junior (тижні 1-2)

Крок Тема Файли Мета
1 Стани Entity Q7, Q8 Transient, Persistent, Detached, Removed
2 Lazy vs Eager Q2, Q3 Коли що використовувати
3 persist vs merge Q14 Який метод для якого стану
4 Cascade база Q20, Q21 Що таке cascade, які типи
5 JPQL vs SQL Q26 Чим відрізняється, коли що

🟡 Рівень Middle (тижні 3-4)

Крок Тема Файли Мета
1 N+1 проблема Q1, Q28 Чому виникає, JOIN FETCH рішення
2 LazyInitializationException Q4 Чому виникає, 3 рішення
3 Dirty checking Q12, Q13 Як працює, коли flush
4 L1 cache Q9 Identity guarantee, snapshot
5 @OneToMany/@ManyToOne Q23, Q24 mappedBy, owner/inverse, helper methods
6 Оптимістичне блокування Q17, Q19 @Version, OptimisticLockException
7 Projection Q29 Навіщо, interface-based, class-based

🔴 Рівень Senior (тижні 5-6)

Крок Тема Файли Мета
1 L2 cache Q10, Q11 Concurrency strategies, clustering, invalidation
2 Pessimistic locking Q18 PESSIMISTIC_READ/WRITE/NONE, NOWAIT, SKIP LOCKED
3 Fetch strategies deep Q5, Q6 FetchMode vs FetchType, SUBSELECT vs BATCH
4 EntityManager vs Session Q16 Internal implementation, Jakarta vs javax
5 Circular cascade Q20, Q22 Cycle detection, orphanRemoval vs REMOVE
6 Criteria API Q27 Type-safe, Metamodel, dynamic queries
7 Inheritance Q30 SINGLE_TABLE vs JOINED vs TABLE_PER_CLASS trade-offs
8 Serialization Q25 Jackson annotations, LazyInitializationException in REST

🔗 Ключові зв’язки між темами

Тема: Fetch та N+1

Q2 (Lazy vs Eager) → Q3 (Коли що) → Q4 (LazyInitException)
     ↓
Q5 (Fetch стратегії) → Q6 (@BatchSize) → Q1 (N+1) → Q28 (JOIN FETCH)

Ключові зв’язки:

  • Q2 ↔ Q5: FetchType (коли) vs FetchMode (як)
  • Q4 ↔ Q28: JOIN FETCH запобігає LazyInitializationException
  • Q5 ↔ Q6: @BatchSize — окремий механізм від FetchMode
  • Q1 ↔ Q29: Projection теж вирішує N+1 (завантажує тільки потрібні колонки)

Тема: Entity Lifecycle

Q7 (Lifecycle) → Q8 (Стани) → Q14 (persist/merge)
     ↓                ↓
Q12 (Dirty check) → Q13 (Flush) → Q15 (refresh)
     ↓
Q16 (EntityManager vs Session)

Ключові зв’язки:

  • Q8 ↔ Q14: persist() для transient, merge() для detached
  • Q12 ↔ Q13: Dirty checking тригерить flush при commit/перед запитом
  • Q15 ↔ Q8: refresh() переводить detached назад в persistent

Тема: Caching

Q9 (L1 cache) → Q10 (L2 cache) → Q11 (L2 налаштування)

Ключові зв’язки:

  • Q9 ↔ Q12: L1 cache зберігає snapshot для dirty checking
  • Q10 ↔ Q11: Конфігурація провайдера, clustering, invalidation

Тема: Relationships

Q20 (Cascade) → Q21 (Cascade типи) → Q22 (Orphan removal)
     ↓
Q23 (@OneToMany/@ManyToOne) → Q24 (Bidirectional) → Q25 (Серіалізація)

Ключові зв’язки:

  • Q21 ↔ Q22: CascadeType.REMOVE vs orphanRemoval
  • Q23 ↔ Q24: Bidirectional вимагає синхронізації обох сторін
  • Q24 ↔ Q25: Bidirectional → нескінченна рекурсія при серіалізації
  • Q25 ↔ Q4: LazyInitializationException при серіалізації LAZY полів

Тема: Query та Inheritance

Q26 (JPQL) → Q27 (Criteria API) → Q28 (JOIN FETCH) → Q29 (Projection)
     ↓
Q30 (Inheritance)

Ключові зв’язки:

  • Q26 ↔ Q27: JPQL — рядковий, Criteria — type-safe
  • Q28 ↔ Q1: JOIN FETCH — головне рішення N+1
  • Q29 ↔ Q26: Projection в JPQL через constructor expression
  • Q30 ↔ Q26: Поліморфні запити залежать від стратегії наслідування

🎓 Шпаргалка: що знати для кожного рівня

🟢 Junior

  • Стани Entity: transient (new), persistent (managed), detached (session closed), removed
  • Lazy = завантаження при зверненні, Eager = одразу. LAZY за замовчуванням для колекцій
  • persist() = INSERT для transient, merge() = SELECT+UPDATE для detached
  • Cascade = автоматичне поширення операцій на пов’язані сутності
  • JPQL працює з entity, SQL — з таблицями

🟡 Middle

  • N+1: 1 запит на батька + N на дочірні. Рішення: JOIN FETCH, @BatchSize, EntityGraph
  • Dirty checking: Hibernate зберігає snapshot, при flush порівнює → UPDATE якщо змінилось
  • L1 cache: на рівні EntityManager, identity guarantee, snapshot для dirty checking
  • @Version: optimistic locking, version=0 при INSERT, +1 при кожному UPDATE
  • orphanRemoval: видаляє дитину при видаленні з колекції, CascadeType.REMOVE — лише при видаленні батька
  • Bidirectional: mappedBy на inverse side, helper methods для синхронізації

🔴 Senior

  • L2 cache: на рівні EntityManagerFactory, clustering (Hazelcast, Infinispan), eventual consistency
  • Pessimistic locking: PESSIMISTIC_READ (shared), PESSIMISTIC_WRITE (exclusive), NOWAIT, SKIP LOCKED
  • FetchMode JOIN ігнорує LAZY в Hibernate 5.x. SUBSELECT тільки якщо батьки завантажені одним запитом
  • Flush order: INSERT → UPDATE → DELETE (критично для FK constraints)
  • Cartesian product при кількох JOIN FETCH — Hibernate 6 не вирішив повністю
  • @MappedSuperclass ≠ @Entity: немає таблиці, не можна query, поліморфні запити не працюють
  • Jackson @JsonManagedReference/@JsonBackReference — не JPA, serializer-specific

📝 Формат кожного файлу

Кожен файл містить:

  • 🟢 Junior Level — базове розуміння, прості аналогії, приклади
  • 🟡 Middle Level — внутрішності, типові помилки, практичні приклади
  • 🔴 Senior Level — deep dive, edge cases, production experience, monitoring
  • 🎯 Шпаргалка для співбесіди — ключові тези, часті запитання, червоні прапорці, пов’язані теми