Раздел 16 · 30 вопросов

Hibernate JPA

30 вопросов и ответов в разделе Hibernate JPA.

Russian 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. States      │        │ 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 states: 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: optimisitc 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
  • 🎯 Шпаргалка для интервью — ключевые тезисы, частые вопросы, красные флаги, связанные темы