Немного о магии под капотом hibernate и в целом. Чисто некоторые интересные моменты. Под капотом hibernate используется jdbc + с добавлением кучи всяких плюх для работы с БД. Если что jdbc это один из способов взаимодействия с БД, в реляционном формате, то есть пишем sql в java коде, уже больно от этой мысли, поэтому спасибо hibernate за возможность работать в объектном формате, то есть работать не с табличками и колонками, а с классами и их полями, также исчезает весь этот boilerplate код то есть трай кетчи, запросы, от чего увеличивается уровень абстракции, и становится удобнее работать, но работает медленнее чем jdbc чисто потому что это еще один уровень логики, еще из плюсов - маппинг, jpql(да да все равно query language нужно будет разобрать) но хотя бы пишем названия классов, полей и концентрируемся на java коде, кеширование, и всякие такие штуки как dirty cheking, lazy loading, flush, action queue. action queue - под капотом hibernate все реализовано на основе определенных событий, то есть происходят какие то события и hibernate на них как то реагирует, а все эти события(actions) hibernate записывает в определенную последовательность / очередь(queue). То есть когда говорим hibernate сделай persist, remove, merge, update, etc., то hibernate не делает это все сразу, он оформляет все это в action и сохраняет в queue, а в момент flush, он берет эту всю очередь и делает execute(выполняет), но делает это не в порядке в котором были добавлены события, а в порядке приоритета. Например операция persist(сохранить в БД) в sql это insert имеет выше приоритет чем update и remove. dirty checking - работает в рамках persistance context, отвечает за обновление данных, то есть update. Где hibernate проверяет меняется ли объект / сущность(entity) если он зафиксировал изменения то посылает в БД update. Как это работает: В момент когда entity загружается в persistance context(если что этот контекст это промежуток работы с бд, то есть выполнение определенной транзакции, где транзакция это некое воздействие на бд), так вот в этот момент создается копия, которая выглядит как массив типа Object, в котором каждый элемент это по сути значение в рядке данных. То есть рядок entity загружается в массив типа Object. Где для каждой entity создается такой массив. Потом в определенный момент, происходит проверка каждого поля(field) сущности(entity) со значением которое находится в этом массиве, то есть с копией. И если какое то значение изменилось генерируется update. Проверка происходит в момент который называется flush. Flush - это момент когда hibernate посылает sql запросов в БД, где flush по умолчанию происходит во время commit. Но flush не значит коммит транзакции, он означает что просто sql пошел в БД, то есть если insert пошел в БД его можно откатить, если выбило ошибку. Так же мне рассказывали что еще flush используется для того что бы подтянуть состояние БД, к своему коду, то есть если кол-во операций много, а коммит скажем так, не скоро, то хотелось бы подтянуть БД к текущему состоянию в коде в java. Так вот, во всех местах когда делаем select и не делаем update нужно выключать dirty checking, потому что он включен по умолчанию, поэтому во всех местах где данные только читаются нужно выключать dirty checking(используем аннотацию read only). lazy loading - механизм который позволяет выгружать данные с БД не сразу, а в момент когда до них обращаемся. Работает только в рамках persistance context иначе вылетит исключение. По идее, дай бог ничего не путаю, хорошо всегда использовать lazy, и при необходимости оверрайдить, что бы избежать вот этого каскадного вытягивания данных, когда хотим загрузить определенную логику, а вытягиваются все зависимости.