Немного о магии под капотом 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, и при необходимости оверрайдить,
что бы избежать вот этого каскадного вытягивания данных, когда хотим загрузить
определенную логику, а вытягиваются все зависимости.
solemnly swear that I am up to no good
21 уровень
№5. Hibernate "under the hood"
Комментарии (27)
- популярные
- новые
- старые
Для того, чтобы оставить комментарий Вы должны авторизоваться
solemnly swear that I am up to no good
27 ноября 2024, 19:52
interesting cases.
Сергей Я
"JDBC - это не способ взаимодействия, а стандарт, так сказать контракт, API, который можно реализовывать. В том числе этим, Java так отличается от того же Golang, где от библиотеки к библиотеки будет отдельный "огород" и потратишь вагон времени чтобы его прочитать."
Сергеев Виктор
"Фишка jdbc как раз в его стандартизации, когда тебе не важна реализация, тебе вообще её могут подкладывать в рантайме. А для тебя как разработчика jdbc интерфейсы будут способом реализации взаимодействия с БД.
http, jdbc, soup, json, xml ... - это все стандарты для интеграций, с их помощью можно взаимодействовать используя различные библиотеки реализующие этот стандарт
Даже сам sql просто стандарт, но мы используем его для взаимодействия с базой. Вроде даже названий для конкретных реализаций нет. pl/sql, pgpl/sql это все такие языки программирования"
Денис
JDBC в разрезе джавки выглядит как унифицированная спецификация для работы именно с базой, он удобен, да, но во первых это ничего не говорит о фактической реализации под капотом... а во вторых, не такая уж и унифицированная если подумать, ведь есть еще и JPA - тоже спецификация по сути и тоже для работы с базой... да это не вполне одно и то же, но в конечном итоге и то и другое используют для манипуляций с данными в базе.
JPA точно так же можно реализовывать как вздумается.
+8
solemnly swear that I am up to no good
3 декабря 2024, 09:28
Сергеев Виктор
Jdbc являясь стандартом, реализуемым поставщиками БД в виде драйверов, является способом взаимодействия, как часть этого самого взаимодействия. "общаемся с БД с помощью jdbc" - подразумевает, что используем спецификацию jdbc, реализованную поставщиком бд в виде jdbc драйвера, которые мы используем, чтобы взаимодействовать с БД.
________________________________________________________________________________
Хибер хорошо работает если у тебя +/- не сложное круд приложение. Если логики становится больше, то приходится уже подключать графы или hql/jpql, еще с n+1 бороться в разных контекстах.
method naming это магия спринга (data-jpa) и в дефолтном хибере ее нет. Я никогда не понимал это желание использовать имена методов вместо запросов, для себе выбрал вариант, что лучше нормальное название и @query
спецификация это некий стандарт для работы с БД - это набор интерфейсов, а дальше автор бд может подготовить свою реализацию этих интерфейсов. За счет этого тот же хибер и работает частично.
Хибер завязался на стандарт java.sql и сможет работать с любой реализацией. Т.к. postgres-jdbc-driver реализейт эти интерфейсы, то хибер может с ними работать П - полиморфизм )
Денис
"но на моменте оптимизации, ты по любому будешь писать sql."
Это если потребуется оптимизация. Далеко не все сервисы высоконагруженные, или требуют прям сложных кверей, ну это по своему опыту сужу. Иногда конечно проще нативку написать, иногда нужно... но не редко хватает и всяких findAllBy...
0
solemnly swear that I am up to no good
6 декабря 2024, 08:12
Сергеев Виктор
по поводу магии и "хочу чисто кодить", вот как пример Например операция persist(сохранить в БД) в sql это insert имеет выше приоритет чем update и remove
А если у меня в бд есть контрейнт на уникальность и я сначала удаляю старое, а потом вставляю новое, тадам - ошибка, но я же сделал все нормально ) а теперь помимо sql, который сгенерит хибер, надо думать в каком порядке он надумает их выполнять )
пример тут https://medium.com/@yevhenii.kukhol/how-is-your-data-actually-flushed-hibernate-actionqueue-event-priorities-d89bc4a91db4
0
Сергей ЯJava Developer в DXC/LuxoftExpert
26 ноября 2024, 18:46
Пишешь чушь.
JDBC - это не способ взаимодействия, а стандарт, так сказать контракт, API, который можно реализовывать. В том числе этим, Java так отличается от того же Golang, где от библиотеки к библиотеки будет отдельный "огород" и потратишь вагон времени чтобы его прочитать.
0
solemnly swear that I am up to no good
27 ноября 2024, 08:31
Ты не согласен только конкретно с этим "это способ взаимодействия" или вообще со всем тем что я написал далее?
Соглашусь что действительно формулировка могла быть более точной,
и назвать стандартом было бы более корректно, хотя и тут можно было бы уточнять еще более конкретно...
Имеешь ввиду если в Golang работать с реляционной БД?
Насколько я понимаю если работать будем с той же монгоДБ, то jdbc тут не подойдет..верно?
0
Сергей ЯJava Developer в DXC/LuxoftExpert
27 ноября 2024, 17:27
Прочитай что такое API и его реализации, что такое контракт. Может после этого вопросов не возникнет.
Это касается и всего остального
0
solemnly swear that I am up to no good
27 ноября 2024, 18:45
Я тебя спросил что бы понять что конкретно тебе не понравилось.
Написать "Полная чушь" и поставить точку очень корректно и умно.
Аргументируй что не так с остальными понятиями про которые я написал,
конкретно по фактам, иначе твое мнение не стоит, ну ничего оно не стоит...
0
Сергеев ВикторMaster
30 ноября 2024, 20:26
Пишешь чушь. http это тоже стандарт, а не способ взаимодействия. Но если ты при проработке системы скажешь что-то типа "давайте использовать стандартизированный текст формата HyperText Transfer Protocol поверх tcp/upd соединения", то конечно часть людей тебя поймут, но нафига так понтоваться, если и "давайте по http взаимодействовать" - понятнее всем.
А то скоро с такими докапываниями начнем изъясняться инструкциями на перемещение транзисторов.
Фишка jdbc как раз в его стандартизации, когда тебе не важна реализация, тебе вообще её могут подкладывать в рантайме. А для тебя как разработчика jdbc интерфейсы будут способом реализации взаимодействия с БД.
http, jdbc, soup, json, xml ... - это все стандарты для интеграций, с их помощью можно взаимодействовать используя различные библиотеки реализующие этот стандарт
Даже сам sql просто стандарт, но мы используем его для взаимодействия с базой. Вроде даже названий для конкретных реализаций нет. pl/sql, pgpl/sql это все такие языки программирования
+2
Сергей ЯJava Developer в DXC/LuxoftExpert
2 декабря 2024, 07:56
http - не стандарт и не набор интерфейсов, в то время как суть Jdbc как раз в стандартизации.
0
Денис Enterprise Java Developer
2 декабря 2024, 08:13
Ну вот по поводу HTTP не соглашусь уже я... если строго описанный (RFC) протокол передачи данных, принятый на вооружение всем миром не является стандартом, то что это?)
Да даже если бы им пользовались полтора землекопа... он все равно "стандартизирован" и ты вынужден действовать по правилам работая с ним.
0
Сергей ЯJava Developer в DXC/LuxoftExpert
2 декабря 2024, 08:20
ок, давайте немного откатимся в вопросе? Что мы подразумеваем в стандарте? Мировой стандарт (протокол само собой имеет свою стандартизацию, так как с ним работают разные технологии, разные языки) или контракт в разрезе языка, описание то как работать с технологией?
Как протокол, да, он имеет свой стандарт (их там целый список), но имхо конечно, в разрезе языка от либы к либе, от фреймворка к фреймворку будет разные контракты для создания сообщения и его отправки. Разве не так?
0
Денис Enterprise Java Developer
2 декабря 2024, 08:33
Ну имхо стандарт он в любом разрезе стандарт, это нечто задокументированное для работы с чем то. А там уже не так важно это калибр патрона, интернет протокол, или апи для работы с базой. Если у тебя на руках есть документация и инструмент, скорее всего ты сможешь им выполнить ту задачу для которой он предназначен, а сила стандарта в том, что это утверждение верно в любой точке земного шара и для любого исполнителя.
У меня недавно состоялся занятный разговор является ли протокол интерфейсом например. Конечно же не является, но и схожие моменты имеются, ведь для взаимодействия с протоколом у тебя есть спецификация - ряд конкретных требований. Ну так и интерфейс это описание конкретных шагов для взаимодействия с системой к которой он прикручен, т.е. та же самая спецификация.
Если рассуждать об HTTP (да любой технологии) в разрезе от либы к либе, конечно же и реализация и интерфейсы могут и будут разными, но в конечном итоге все они будут делать одно и то же - формировать конкретный пакет данных и класть их конкретным образом в конкретное место... ну грубо говоря. Т.е. либа это не более чем обвязка над технологией.
JDBC в разрезе джавки выглядит как унифицированная спецификация для работы именно с базой, он удобен, да, но во первых это ничего не говорит о фактической реализации под капотом... а во вторых, не такая уж и унифицированная если подумать, ведь есть еще и JPA - тоже спецификация по сути и тоже для работы с базой... да это не вполне одно и то же, но в конечном итоге и то и другое используют для манипуляций с данными в базе.
JPA точно так же можно реализовывать как вздумается.
+1
Сергей ЯJava Developer в DXC/LuxoftExpert
2 декабря 2024, 09:04
мы говорим об одном и том же, но на разных языках.
0
Сергеев ВикторMaster
3 декабря 2024, 01:49
если прям совсем откатиться, то я не согласен с
"JDBC - это не способ взаимодействия"
Jdbc являясь стандартом, реализуемым поставщиками БД в виде драйверов, является способом взаимодействия, как часть этого самого взаимодействия. "общаемся с БД с помощью jdbc" - подразумевает, что используем спецификацию jdbc, реализованную поставщиком бд в виде jdbc драйвера, которые мы используем, чтобы взаимодействовать с БД.
В общем я скорее к тому, что наверно не стоит так докапываться до использованных слов, если они не меняют суть. Можно говорить, что взаимодействуем с БД используя ЭВМ с заранее написанными инструкциями для процессора посылая электроны ...(тут описать всю модель osi от 0 до 7 на сервере и от 7 до 0 на сервер БД и обратно)
Но зачем, если мы используем jdbc для общения с БД и именно это важно в контексте статьи (и то не сильно важно, а просто небольшое предисловие)?
+2
Сергей ЯJava Developer в DXC/LuxoftExpert
3 декабря 2024, 07:06
Причина моих докапывание состоит в первом абзаце.
- "Под капотом hibernate используется jdbc + с добавлением кучи всяких плюх для работы с БД" - само собой, что на низком уровне будет использована спецификация Jdbc. Это как сказать "Под капотом автомобиля будет использован поршень в камере сгорания". "Куча плюх"? Какие? Где?
"то есть пишем sql в java коде, уже больно от этой мысли, поэтому спасибо hibernate" - от мысли писать SQL в Java коде не то, что не больно, а ты по любому будешь писать sql, так как Hiber увеличивает в раз скорость разработки, но на моменте оптимизации, ты по любому будешь писать sql.
"еще из плюсов - маппинг" - это не еще один плюс, это основная идея Хибера, хотя бы потому, что он ORM, что есть одной из реализаций JPA.
То есть первый абзац написан в формате "масло-масленное", пропущено много важного с прыжками из крайности в крайность, хотя как уже говорил, на портале есть статьи которые объясняют эту тему гораздо подробней, проще и лучше.
0
Денис Enterprise Java Developer
3 декабря 2024, 09:57
но на моменте оптимизации, ты по любому будешь писать sql.
Это если потребуется оптимизация. Далеко не все сервисы высоконагруженные, или требуют прям сложных кверей, ну это по своему опыту сужу. Иногда конечно проще нативку написать, иногда нужно... но не редко хватает и всяких findAllBy...
А вообще с Виктором соглашусь, заниматься буквоедством, если сути это не меняет, наверное не стоит. В конце концов есть куча разных источников одной и той же информации разной степени водянистости и масляности, просто на каждый формат свой потребитель.
0
solemnly swear that I am up to no good
3 декабря 2024, 10:22
Абсолютно искренне, стараясь конструктивно, отвечаю.
все что не может чисто jdbc все в hibernate, это и будут те самые фишки фреймворка...
Классы, Интерфейсы, методы, маппинг, jpql, всякие штуки для работы с транзакциями,
всякие проверки, приоритетность, уверен еще много всего...Но эти пункты что я написал первые что бросаются мне в глаза как новичку.
Так я для себя понял, это мой ответ на "какие и где".
Какие бы ты плюсы назвал? Минусы?
Зачем мне писать sql если я наоборот хочу перестать писать в реляционном формате, а хочу работать с классами и полями, вместо таблиц, колонок и т.п., хочу как джава программист работать с ORM. Я буду писать jpql / использовать method naming...
Насколько я понимаю Hibernate увеличивает скорость разработки за счет того что бы не писать boilerplate код(лишние траи кетчи, запросы и тп), позволяет писать на более высоком уровне абстракции, однако мы всегда можем опуститься к jdbc.
Однако в целом работает медленее, чисто потому что это дополнительные классы интерфейсы... etc.
То есть мы с hibernate намного быстрее решим задачу, которая будет работать медленее,
на фоне jdbc, но ту же задачу на jdbc будем решать дольше...
Так? Не так?
Почему это не еще один плюс на фоне остальных, и на фоне чисто jdbc?
0
solemnly swear that I am up to no good
3 декабря 2024, 10:22
Это не статья, не туториал, не гайд, этим постом я выразил как я для себя понял hibernate,
в общих рамках, какие то моменты, не про все я написал это не вместилось бы в пост, скорее это из разряда "как бы я ответил на некоторые вопросы если бы их задали на собесе".
Поэтому это в разделе "Форум".
Теперь думаю что не буду говорить что jdbc способ взаимодействия, т.к. возможно так и можно сказать, но тогда такой ответ может вызвать вопросы, буду говорить что это спецификация, видимо так более корректно, где насколько я понимаю спецификация это некий стандарт для работы с БД, в данном случае с реляционными БД.
Верно? Нет?
Цель поста, по мимо того что бы построить мысль свою, а не просто заучить понятие из википедии, а так же в чем то затригерить более опытных разработчиков, что бы они добавили, и как то по другому рассказали как они с высоты опыта видят то про что я написал.
Потому что именно в общении, и диалоге, лучше выяснить что и как устроенно...
То есть я для себя выясняю некие моменты...
0
Сергеев ВикторMaster
5 декабря 2024, 22:33
вот против такого докапывания ничего не имею )
только вот "само собой, что на низком уровне будет использована спецификация Jdbc" - кажется, что не для всех "само собой", для некоторых, особенно начинающих, особенно после видео "подключите spring data jpa и не пишите sql никогда" может быть действительно не очевидно )
0
Сергеев ВикторMaster
5 декабря 2024, 22:52
"все что не может чисто jdbc все в hibernate, это и будут те самые фишки фреймворка...
Классы, Интерфейсы, методы, маппинг, jpql, всякие штуки для работы с транзакциями,
всякие проверки, приоритетность, уверен еще много всего...Но эти пункты что я написал первые что бросаются мне в глаза как новичку."
Ты тут описал что умеет хибер. Это действительно как Сергей написал, как сравнивать двс и поршень ) Нет поршня, нет двс ) Кстати транзакции это тоже из спринга (сама анноташка)
Убери из хиюера jdbc и ничего из этого работать не будет )
Хибер прикольная штука, просто сравнение не корректное
Зачем мне писать sql если я наоборот хочу перестать писать в реляционном формате
Наши желания и наши возможности не всегда совпадают. Хибер хорошо работает если у тебя +/- не сложное круд приложение. Если логики становится больше, то приходится уже подключать графы или hql/jpql, еще с n+1 бороться в разных контекстах.
Ничего плохого в этом взгляде нет. Просто через какое-то время ты поймешь, что хибер не освободит тебя от работы с бд, это просто один из вариантов решения конкретных задач.
"хочу как джава программист работать с ORM. Я буду писать jpql / использовать method naming..."
method naming это магия спринга (data-jpa) и в дефолтном хибере ее нет. Я никогда не понимал это желание использовать имена методов вместо запросов, для себе выбрал вариант, что лучше нормальное название и @query
"То есть мы с hibernate намного быстрее решим задачу, которая будет работать медленее,
на фоне jdbc, но ту же задачу на jdbc будем решать дольше..."
В теории да, но важно понимать куда продукт будет развиваться дальше. Если сложнее чем круд, то возможно будет сложнее дальше бороться с разными сложностями.
+1
Сергеев ВикторMaster
5 декабря 2024, 22:55
спецификация это некий стандарт для работы с БД - это набор интерфейсов, а дальше автор бд может подготовить свою реализацию этих интерфейсов. За счет этого тот же хибер и работает частично.
Хибер завязался на стандарт java.sql и сможет работать с любой реализацией. Т.к. postgres-jdbc-driver реализейт эти интерфейсы, то хибер может с ними работать П - полиморфизм )
+1
Сергеев ВикторMaster
5 декабря 2024, 23:18
по поводу магии и "хочу чисто кодить", вот как пример Например операция persist(сохранить в БД) в sql это insert имеет выше приоритет чем update и remove
А если у меня в бд есть контрейнт на уникальность и я сначала удаляю старое, а потом вставляю новое, тадам - ошибка, но я же сделал все нормально ) а теперь помимо sql, который сгенерит хибер, надо думать в каком порядке он надумает их выполнять )
пример тут https://medium.com/@yevhenii.kukhol/how-is-your-data-actually-flushed-hibernate-actionqueue-event-priorities-d89bc4a91db4
+1
solemnly swear that I am up to no good
6 декабря 2024, 08:09
Спасибо, Виктор, за ответы, я их конспектирую, учу, еще с chatgpt прогоняю, что бы он мне объяснял тоже..
Классная ссылка, начал читать.
Стараюсь выучить как работать с бд, уже все варианты попробовал делал разные не сложные приложения и с jdbc и hibernate и + jpa и spring data, и вместе и раздельно,
а сейчас углубляю свои знания, вот aop тоже немного разобрал, буду глядеть как туда вынести логику работы с транзакциями...
0
Сергеев ВикторMaster
6 декабря 2024, 20:01
моя рекомендация - учи базовые штуки.
sql, http (и сервлеты, хотя бы пару сам напиши), html/js/css
орм, спринг веб, они упрощают работу с этими инструментами.
Но если ты знаешь sql, то тебе нужно немного времени, чтобы начать использовать любую орм (именно строить запросы, а не тонкие настройки), потому что все они оборачивают обычный sql.
Тоже самое с http, если знаешь структуру запроса, то знаешь что тебе нужно сделать, а как подскажет документация к либе, будь то спринг, микронавт, кваркус или что либо другое
Ну и помимо этого ты становишься более хорошим и ценным специалистом. Если ты знаешь только хибер и понятие не имеешь про sql то сильно срезаешь варианты будущей работы.
В системах под нагрузкой могут применяться различные хаки в бд, которые хибернейт сделать не даст. Например работа с временными таблицами
+4
solemnly swear that I am up to no good
6 декабря 2024, 22:33
Класс, понял!
Но вопрос, а html/js/css стоит ли? то есть это же фронт...
0
Сергеев ВикторMaster
6 декабря 2024, 22:44
ну есть такое понятие как Т люди. Это когда ты хорошо знаешь свою область (бекенд), но в то же время немного знаком с областями вокруг (фронт, девопс, работа БД)
Полезно знать многое, хотя бы в минимальном наборе. Например немного поработав с фронтом можно несколько корректнее проектировать rest api учитывая то, как будет работать фронт, понимать почему они просят что-то не стандартное например. Объяснить девопсу как запускать твое приложение, или использовать плюшки окружения.
Так то и sql можно спихнуть на дба, но он есть не всегда и не везде.
А html/js/css ну взять тот же thymeleaf, не зная html нормальные шаблоны не сделаешь, не зная что такое css и как его подключить не сделаешь его хоть сколько-нибудь презентабельным, а без js придется не rest api делать, а server side page
В общем все это опциональное, но повышает опыт, позволяет лучше взаимодействовать с командой, понимать как твои действия влияют на общий процесс.
Ну а иногда это даст тебе возможность самому с нуля сделать проект полностью
+1
solemnly swear that I am up to no good
6 декабря 2024, 23:06
Ок) разберем)
0