Search
Write a publication
Pull to refresh

Comments 37

Ручное написание подобного кода, как правило, приводит к громоздкому, хрупкому решению, которое трудно оптимизировать впоследствии

На слове "громоздкий" сложно на засмеяться. Хибер-то зато легковесный, да. Наш самописный маппер ResultSet -> T это 1 класс на 350 строк, а вся магия в 1 функции на 70 строк. Написано и протестировано один раз более 3 лет назад - работает как часы. Не думаю, что у хибера аналогичная логика принципиально компактнее и быстрее. Как бы не наоборот.

Такие вот пассажи демотивируют доверчивых новичков и заставляют тянуть в проекты тонну зависимостей вместо простых самописных решений.

Если вам повезло, что за 3 года у вас не усложнилась модель работы с БД, это не значит, что у других тоже не усложнится.

Из проектов с самописной ОРМ, которые я видел, в такую систему изменения вносились несколько раз в год, и каждый раз через страдания.

Хибернейт такой большой не потому что его писали неумелые разработчики, которым платили за каждую строчку кода. А потому что там покрыто огромное количество edge cas'ов, которые вам, к счастью, не попадались. Ну, либо, вы лукавите и за 3 года вносили не одно изменение, но успешно про это забыли.

Аргумент работает и в другую сторону. Если у вас усложнилась, не факт, что у других усложняется. Если бы хибер не был так сложен, не появился бы spring-data-jdbc. Что только не придумают, лишь бы SQL не учить)

Ваш аргумент тоже работает в другую сторону))

Что только не придумают, лишь бы хибернейт не учить

самодельные 

А чем, собственно, самодельные решения отличаются от не-самодельных? Их какие-то боги пишут вместо простых смертных?

А чем, собственно, самодельные решения отличаются от не-самодельных?

Тем, что в не-самодельных решениях накапливаются оптимальные решения для всех типичных кейсов

Их какие-то боги пишут вместо простых смертных?

Собственно да. Не боги, но люди, которые годами занимаются именно этими решениями.

Вы забыли про обратную сторону монеты. Очень часто такие решения сильно избыточны, сложны, создают препятствия при оптимизации, тянут за собой зависимости и обрастают костылями обратной совместимости.

наличием тестов

и… собственным самодельным ORM, к которому я неизбежно приду в попытках решить те же задачи

Собственно, да. Проблема реляционных данных в том, что они напрямую на экран пользователя не попадают. Они проходят через промежуточный слой - слой приложения. Которое, как правило, объектно-ориентированное. И в нём удобно работать со строкой из таблицы, как с объектом. Поэтому, как ни крути, а объекто-реляционный маппинг данных будет.

Основная проблема ORM в том, что это лишняя абстракция, нюансы работы которой нужно знать. И SQL тоже нужно знать обязательно. В итоге получается, что эту абстракцию можно выкинуть и не ухудшать свой developer expirience. Проблема мапперов на мой взгляд переоценена.

Основная проблема ORM в том, что это лишняя абстракция, нюансы работы которой нужно знать

Абстракция, нюансы работы которой нужно знать, да. Но что она лишняя это ещё надо доказать.

И SQL тоже нужно знать обязательно.

Знание SQL это общее место. Неожиданно, что ещё надо знать, как работает jdbc.

В итоге получается, что эту абстракцию можно выкинуть и не ухудшать свой developer expirience.

Разрабатывать с помощью голого jdbc без Hibernate? Я подозреваю, что вы уже очень давно этого не делали. Экспириенс ухудшится и ещё как

Голый JDBC вовсе не обязателен. Spring Data JDBC умеет маппить результаты SQL-запросов прямо в DTO. По соответствию имен полей DTO и имен (псевдонимов) полей таблицы.

Голый Spring JDBC тоже умеет мапить имен полей DTO и имен (псевдонимов) полей таблицы. Прям из коробки, есть RowMapper для этого, называется - org.springframework.jdbc.core.DataClassRowMapper (если через data class/record) или org.springframework.jdbc.core.BeanPropertyRowMapper (если через setter). При желании всегда можно написать свой универсальный RowMapper под любые цели.

Spring Data JDBC умеет маппить результаты SQL-запросов прямо в DTO

И вот дискуссия из ORM не нужны плавно перетекает в плоскость - я не люблю Хибернейт. А люблю Spring Data JDBC. То есть Hibernate, который правильно приготовлен ))

Именно так. Решения, в которых количество магии сократили до минимума, как правило, надежнее всего. А с hybernate ещё сиди и думай, какая у него политика фетчинга, в какой он это все запрос в итоге соберёт (или много запросов, когда нужен 1), в какой момент он захочет, за кэшировать, в какой нет, какой эвикшн полиси для него настроен, как вручную эвиктить и т. д.

Разрабатывать с помощью голого jdbc без Hibernate? Я подозреваю, что вы уже очень давно этого не делали.

Уже много лет использую только jdbcTemplate и его производные

Уже много лет использую только jdbcTemplate и его производные

А какие производные имеются в виду? Интересно, что получается всё-таки, какая-то ещё абстракция вам нужна и вы почему-то не считаете её лишней. Любопытно чего вам хватает

JdbcTemplate/NamedParametersJdbcTemplate и в последнее время JdbcClient. Используются чистые sql запросы и именованные параметры внутри них.

Но что она лишняя это ещё надо доказать.

Вообще-то наоборот. Следуя принципу KISS и бритве Оккама, доказывать надо, что она нужна.

А еще это как правило runtime расходы (да я знаю, что там многое оптимизировано и кэшировано) дополнительно.
Та же генерация кода тоже позволяет делать проверки правильности моделей, но время тратится один раз при компиляции, а не каждый раз (при запуске как минимум).

Особенно порадовало про прелесть работы с графом объектов вместо «табличного» представления данных.
Вот тут то проблемы и начинаются.
Визуализировать и правильно работать с табличными данными может любая обезьяна, включая чат гпт.

А с графами у каждого первого проблемы

Может, проблема в том, что объекты и "графы" частенько тащат туда где они не нужны? Или наоборот, объектные данные со сложной структурой, раскидывают по десяткам хитроизнасилованных таблиц педантично следуя всем известным нормальным формам, там где стоило бы сохранить JSON в блоб (или jsonb)?

гораздо более переносим между различными СУБД

вот этот аргумент у хибернейта я особенно люблю. а вот эта переносимость между разными субд с сохранением структуры данных и запросов - она сейчас с нами в этой комнате? её кто-нибудь когда-нибудь в реальной жизни встречал?

или всё же речь про смену базы заходит, когда выясняются какие-то фундаментальные проблемы текущего решения и надо полностью переделывать структуру данных под новые требования?

Мы для своего решения делали: у разных заказчиков стояли разные БД (oracle и postgres), и по требованиям наша система должна была работать с их базой данных. Наша система устанавливалась на их сервера и не имела доступа в интернет.

Но я с вами согласен, что это прям очень редкий кейс. Более крупные on premise решения могут диктовать заказчикам свои условия.

Для Saas это ещё менее актуально. Хотя иметь возможность свалить на что-то более удобное/дешёвое, это всегда приятно. Никто не любит vendor lock

Аргумент переносимости на другую базу данных просто бесит. Количество случаев, когда это действительно нужно, стремится к нулю. Я ни разу за 20 лет своей карьеры не встречал такого кейса.

В реальности в любом реальном проекте почти всегда появляются SQL-хаки, которые как раз нужны для компенсации ограничений ORM при работе с какой-то конкретной базой данных. Ведь, чтобы ORM стала универсальной, создателям как раз и приходится выбрасывать фичи конкретных баз, которые отсутствуют в других базах.

И вот, имея такие вот хаки, я получаю задание на переезд на другую базу данных. И где же тогда та хвалёная переносимость? А нет её, и никогда не было.

 Количество случаев, когда это действительно нужно, стремится к нулю. Я ни разу за 20 лет своей карьеры не встречал такого кейса.

Именно что не встречали. С 2014 года много информационных систем переносились с MSSQL и Oracle на Postgre.

Мне в современном мире Java скорее SQL — это дополнение к Hibernate. В остальном, как обычно, всё очень непросто определить, как обычно, качели между «дольше разработка, но быстрее скорость работы» и «ввяжемся в бой побыстрее, а потом поймём, что нам делать».

Как всегда комментарии под сомнительной статьей интересней статьи и гораздо полезнее ;-)

ORM всегда выглядит привлекательно на начальных этапах разработки, потому что позволяет делегировать сложность проекта магической машинке, делающей всё за тебя. Многие проекты с хорошей ORM можно собрать буквально за день.

Почему же люди говорят, что ORM - это плохо? А потому что если на начальном этапе проекта ORM невероятно помогает, то когда проект становится сложнее и требует нестандартных подходов к решению проблем, возникающих в процессе развития, увеличения нагрузки и изменения бизнес-логики, то программисты вместо получения оргазма от магии ORM всё чаще начинают с ней бороться.

А борьба с такой сложной штукой, как ORM - это тяжко. Бороться с магией нелегко. Но решать-то проблемы надо, и часто приходится использовать плохие решения. В результате проект может превратиться в набор настолько ужасающих костылей, что внесение изменений в него превращается в сильную боль.

Сложно потому, что "самописанные" orm никак не документированы и не имеют достаточного "срока жизни" для отладки работы их кода. Использование orm без связи с "готовым решением" вообще зачастую не имеет смысла, так как кроме самой orm там должна быть целая "обвязка" для связи orm с интерфейсом пользователя и системой безопасности доступа к данным и интерфейсу пользователя. А в больших системах еще разграничения по организациям, группам пользователей и много еще чего. И все это должно работать "как часы", поэтому и отлаживается такое многими годами тысячами разработчиков. Плюс , в таких "готовых" решениях всегда есть модуль покрытия тестами разрабатываемых модулей, а это еще одна большая подсистема .

На orm написаны сложные системы тысячами программистов. Например, odoo - это готовая erp система, основанная на orm, "вылизываемая" уже лет 20. И там речь идет не только о доступе к данным, а также о их представлении пользователю в backend приложении, безопасности доступа к данным и интерфейсу пользователя. Скорость разработки в такой среде в разы выше, чем в обычной среде с использованием обычного sql доступа. Вхождение в такую готовую систему новых разработчиков также сокращается в разы в виду связанных между собой моделей данных, а не sql представленных разных таблиц . ORM создает трехслойную структуру к данным и обеспечивает быстрый кэш доступ к изменяемым одновременно из разных источников данным. Современным AI также проще работать с orm моделями, чем разбираться с разными SQL таблицами. Современные AI , например, знают erp odoo как систему продаж со связанными внутри разными бизнес процессами и построение внутри новых orm моделей через AI значительно упрощает разработку новых модулей в данной системе.

Пробовал гибернейт после питоновских орм - понимаю боль. Джава сама по себе не очень выразительна для этих задач

ORM не сам по себе ценен, а в экосистеме. Если у вас есть способ автоматически генерировать энтити, валидировать, что ваши энтити совпадают с базой и делать типобезопасные запросы поверх энтитей, которые может проверить компилятор, то это безусловно значительно лучше, чем писать голый sql. Если же у вас ничего этого нет и всё делается руками, то вопрос о том имеет ли смысл использовать голый sql может иметь место.

Не знаю. Я вернулся обратно к идее ОРМов. Ну вот есть программа на 70 таблиц.

И все бы здорово, но все эти Мапперы требуют хороших прямых рук. Я бы хотел посмотреть на логику того как кто-то запихивает посты в юзер объект и как такая штуковина называется. Или когда к посту надо присобачить автора. Все это обрастает портянками бойлерплейт кода. Например где надо вставить в пост автора, а в автора посты. Мелочь, создаёт лишний способ ошибиться. И все со временем становится хуже чем стандартный хибер подход.

Отдельная боль это транзакции, если товарищ решил все делать без аннотаций, везде тащит объект коннекшены с собой и не совсем понятно где начинать и какие там пулы создавать. H2 не запустить, а с хибером это просто, не хотим мы ставить локальный оракул например.

Отдельным плюсом какая никакая валидация таблиц у хибера, правда хорошо жрет время старта

Тоже самое могу сказать про entity framework без него вся логика фреймворка лежала бы в приложении а не библиотеке. Авто походу не работал в крупных бизнес проектах где таблиц в бд 250+

Тоже самое могу сказать про entity framework без него вся логика фреймворка лежала бы в приложении а не библиотеке

Я процитирую кусок из статьи

А значит, выбор будет между полноценным, зрелым и мощным решением вроде Hibernate — и… собственным самодельным ORM, к которому я неизбежно приду в попытках решить те же задачи.

Так что то, о чём вы говорите есть прямо в тексте статьи

Люди которые рассуждают нужен ли ИМ ЛИЧНО hibernate или нет по всей вилимости являются разработчиками начального или среднего уровня, и/или участникми проектов невысокой сложности (хотя их собственные представления о сложности проектов в которых они участвуют могут быть иными конечно)

В чем тут суть?. Приведу пример(ы)

Недавно один из членов моей команды получил задание (да, от меня лично) написать небольщой микросервис, который возьмет данные из некоего внешнего источника (REST API) и по каждой строке оного обновит данные в таблице БД. Это все. Я не требовал даже использовать java или kotlin - хочешь python или golang - не вопрос (не ну ограничения в жтом плане все равно были кончено мне зоопарк нафиг не нужен). Но сервис был написан на java и с использованием EclipseLink. Ну что я могу сказать... сервис пришлось переписывать. Причем сразу как только я его увидел - в данном случае никакие фреймворки навиг не нужны, включая и Spring Boot. Думаю не стоит пояснять почему, да?

Но есть и другие примеры, касающихся носителей идеологии "сам все напишу" - К превеликому сожалению мне очень часто приходится расхлебывать последствия таких вот пейсателей - легаси проекты которые как-то работают, но никто не знает как именно, а любая, сколь угодно малая модификация это вызов, за который можно давать премии (и порой даже дают).

Начинается ведь все просто.. Зачем нам hibernate - 5-6 SQL запросов.. делов-то.. потом 5-6 запросов превращаются в 30-50, адобавление млу удаление одного поля приводит в необходимости согласовано модифицировать код в нескольких местах, причем места эти часто располагаются в нескольких файлах - к этому времени пытливая мысль разработчика обычно уже доходит до необходимости хранить названия таблиц и полей в константах, а константы в каком-то специальном файле или файлах - это конечно помогает в случае переименования полей, но вот в случае добавления или удаления поля как-то не особо. Но постоянно ведь вылезают новые проблемы - вдруг выясняется, что таблицы могут находиться в разных схемах, а бывает, что и схема-то создается на лету и динамически (не спешите клеить ярлыки вроде "плохой дизайн" - дизан всегда диктуется внешними обстоятельствами). Потом раз! Извольте индексы использовать!

Да, пытливого разработчика не остановить! он решит все проблемы в конченом итоге.. особенно если ему заплатить (хотя бывает, что это не обязательно) - я например видел как создают свои data annotations, к которым придашается код по конвертации оных в SQL запросы... и постепенно проглядывается... ORM! Хороший ли, плохой, но ORM.

И вот тут самое время задать вопрос - зачем было заниматься этим рукоблудием, вместо того, чтобы взять полноценный ORM фреймвок, отлаженный трудом тысяч разработчиков?!

И вот тут начинается то, что отличает зрелого разработчика от.. не очень зрелого (причем речь не идет о количестве лет опыта!). Тот кто говорит, что он написал фреймвок который ничем не хуже, во первых в подавляющем большинстве случав не может сравнивать - просто потому, что он не изучал глубоко другие фремворки (как правило это так - попробовал-не получилось-не понравилось-написал свой велосипед). Но даже если допустить, что доморощенный фреймворн ничуть не хуже, да пусть даже лучше в каких-то местах, автру-гению почему-то не приходит в голову, что на это потрачены ДЕНЬГИ! деньги работодателя, причем не только, а часто и не столько на зарплату этого гения. И этих трат можно было бы избежать.

квалифицированный разработчик оперирует не своими хотелками а экономической эффективностью. Ему нужно решить некую техническую проблему. И если эту проблему можно решить с посмошью hibernate или другого ORM фреймворка он будет решать ее именно так.

Многое конечно зависит от самой постановки этой проблемы - бывает, что проблема описывается как сиюминутная задача. Но чаще всего опытный специалист решает задачу имея в виду полный жизненный цикл своего решения (даже если он собирается уволиться через неделю) - он сразу думает о том, как оно может расширяться вширь вглубь в высоту и по диагонали. Причем он отлично понимает, что он не в состоянии вредвидеть всего, и просто старается упростить работу (как свою так и своих коллег, большинство из которых он никогда в этой жизни не увидит) при любом развитии событий

Я к слову сказть за свою жизнь написал 2 полноценных ORM (ну до функциональности Hibernate они конечно даже близко не дотягивали) - один из них был написан когда никаких фреймвоков подобного рода даже в зародыше не существовало, второй был очень и очень специализированный. Я даже могу сказать, что мне это понравилось! Но я получаю деньги не за то, что делаю то что мне нравится - я решаю проблемы своих работодатателей, когда я employee или своих клиентов если я консультант.

И тут я нахожусь в очень конкурентной среде - используя решения которые с экономической точки зрения менее выгодны чем то что предлагается моими конкурентами я теряю деньги. Свои деньги. не знаю кому как а мне лично это не нравится. Гораздо, неизмеримо больше не нравится чем могут не наравиться любые фреймворки!

Sign up to leave a comment.