Сущность отличается от произвольного объекта
Сущность представляет данные с устойчивой идентичностью. Идентификатор позволяет связать объект с определенной записью, даже если другие значения меняются. Отображение задает соответствие свойств и столбцов, а связи описывают отношения между сущностями. Например, заказ связан с покупателем и набором позиций. В объектной модели это ссылки и коллекции, в реляционной — ключи и связанные таблицы. Различие важно: обращение к привычному свойству объекта может потребовать отдельного запроса. Поэтому структуру модели проектируют вместе с ожидаемыми сценариями чтения и изменения, а не только по удобству классов.
Контекст хранения отслеживает состояние
Session или EntityManager управляет контекстом хранения, внутри которого сущности имеют определенный жизненный цикл. Управляемый объект может отслеживаться на предмет изменений, а отделенный от контекста требует другого обращения. Транзакция задает границы согласованной работы с базой, но ее нельзя путать с любым временем жизни объекта в памяти. Момент отправки изменений также не всегда совпадает с каждой строкой прикладного кода. Для понимания полезно наблюдать SQL и знать, когда происходит синхронизация. Слишком долгоживущий контекст накапливает состояние, а неясные границы усложняют объяснение того, какие изменения будут сохранены.
Ленивая загрузка требует явного плана
Ленивая загрузка откладывает получение части связанных данных до обращения к ним. Это помогает не читать лишнее, но может привести к серии отдельных запросов. Типичная проблема возникает, когда приложение сначала получает список заказов, затем для каждого запрашивает связанную информацию. Число обращений растет вместе с размером списка. Обратная крайность — всегда загружать все связи — тоже увеличивает объем данных. Подход выбирают под конкретный сценарий: заранее нужные связи, подходящий запрос или отдельное представление результата. Обращение к незагруженной связи после завершения доступного контекста может завершиться ошибкой. Поэтому проверка включает границы работы с сущностями и реальное число запросов.
Попробуйте на практике
Спроектируйте чтение списка заказов на бумаге без настройки базы и установки библиотек.
- Нарисуйте три сущности: заказ, покупатель и позиция заказа. Укажите идентификаторы и связи, затем сопоставьте их условным таблицам.
- Опишите экран, которому нужны номер заказа, имя покупателя и итоговая сумма, но не полный список позиций. Отметьте действительно необходимые данные.
- Сравните два плана: отдельный запрос покупателя для каждого заказа и заранее подготовленное чтение нужных полей. Посчитайте условное число запросов для десяти заказов в первом варианте.
- Обозначьте границу транзакции и момент формирования данных для экрана. Укажите, какие ленивые связи не должны неожиданно читаться после завершения этого этапа.
Как проверить результат. Модель различает объекты и таблицы, экран не требует лишних данных, а в наивном плане замечены один исходный и десять дополнительных запросов. Границы контекста описаны явно.
Частые вопросы
Избавляет ли Hibernate от необходимости знать SQL?
Нет. ORM формирует запросы, но их стоимость и поведение зависят от базы. Знание SQL помогает проверять выборки, индексы, объединения и причины лишних обращений.
Нужно ли везде включать немедленную загрузку связей?
Нет. Универсальная стратегия редко подходит всем сценариям. Нужные данные определяют по конкретной операции, а результат проверяют по SQL, объему выборки и числу запросов.
Самостоятельный разбор темы. Содержание конкретной обучающей программы здесь не представлено.