Hibernate JPA
30 вопросов и ответов в разделе Hibernate JPA.
Вопросы этого раздела
- Что такое проблема N+1 и как её решить
- В чём разница между Lazy и Eager загрузкой
- Когда использовать Lazy, а когда Eager loading
- Что такое LazyInitializationException и как её избежать
- Какие стратегии fetch существуют в Hibernate
- Что делает аннотация @BatchSize
- Опишите жизненный цикл Entity в Hibernate
- Что такое состояния transient, persistent, detached, removed
- Что такое кэш первого уровня в Hibernate
- Что такое кэш второго уровня и когда его использовать
- Как настроить кэш второго уровня
- Что такое dirty checking в Hibernate
- Как работает механизм flush в Hibernate
- В чём разница между persist() и merge()
- Что делает метод refresh()
- Что такое EntityManager и чем он отличается от Session
- Как реализовать оптимистичную блокировку в JPA
- Как реализовать пессимистичную блокировку в JPA
- Что такое @Version и зачем она нужна
- Как работают каскадные операции (Cascade)
- Какие типы Cascade существуют
- Что такое orphan removal
- Как правильно использовать @OneToMany и @ManyToOne
- В чём особенности bidirectional relationships
- Как избежать бесконечной рекурсии при сериализации Entity
- Что такое JPQL и чем он отличается от SQL
- Что такое Criteria API и когда его использовать
- Как использовать JOIN FETCH для решения проблемы N+1
- Что такое projection в JPA
- Какие типы наследования поддерживает JPA
Навигатор по разделу
30 вопросов для подготовки к собеседованию на Middle Java Developer.
📋 Все вопросы
🗺️ Карта зависимостей тем
┌──────────────────────────────────────────┐
│ 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
- 🎯 Шпаргалка для интервью — ключевые тезисы, частые вопросы, красные флаги, связанные темы