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 и его производные
А какие производные имеются в виду? Интересно, что получается всё-таки, какая-то ещё абстракция вам нужна и вы почему-то не считаете её лишней. Любопытно чего вам хватает
Но что она лишняя это ещё надо доказать.
Вообще-то наоборот. Следуя принципу KISS и бритве Оккама, доказывать надо, что она нужна.
А еще это как правило runtime расходы (да я знаю, что там многое оптимизировано и кэшировано) дополнительно.
Та же генерация кода тоже позволяет делать проверки правильности моделей, но время тратится один раз при компиляции, а не каждый раз (при запуске как минимум).
Особенно порадовало про прелесть работы с графом объектов вместо «табличного» представления данных.
Вот тут то проблемы и начинаются.
Визуализировать и правильно работать с табличными данными может любая обезьяна, включая чат гпт.
А с графами у каждого первого проблемы
гораздо более переносим между различными СУБД
вот этот аргумент у хибернейта я особенно люблю. а вот эта переносимость между разными субд с сохранением структуры данных и запросов - она сейчас с нами в этой комнате? её кто-нибудь когда-нибудь в реальной жизни встречал?
или всё же речь про смену базы заходит, когда выясняются какие-то фундаментальные проблемы текущего решения и надо полностью переделывать структуру данных под новые требования?
Мы для своего решения делали: у разных заказчиков стояли разные БД (oracle и postgres), и по требованиям наша система должна была работать с их базой данных. Наша система устанавливалась на их сервера и не имела доступа в интернет.
Но я с вами согласен, что это прям очень редкий кейс. Более крупные on premise решения могут диктовать заказчикам свои условия.
Для Saas это ещё менее актуально. Хотя иметь возможность свалить на что-то более удобное/дешёвое, это всегда приятно. Никто не любит vendor lock
Аргумент переносимости на другую базу данных просто бесит. Количество случаев, когда это действительно нужно, стремится к нулю. Я ни разу за 20 лет своей карьеры не встречал такого кейса.
В реальности в любом реальном проекте почти всегда появляются SQL-хаки, которые как раз нужны для компенсации ограничений ORM при работе с какой-то конкретной базой данных. Ведь, чтобы ORM стала универсальной, создателям как раз и приходится выбрасывать фичи конкретных баз, которые отсутствуют в других базах.
И вот, имея такие вот хаки, я получаю задание на переезд на другую базу данных. И где же тогда та хвалёная переносимость? А нет её, и никогда не было.
Мне в современном мире 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 или своих клиентов если я консультант.
И тут я нахожусь в очень конкурентной среде - используя решения которые с экономической точки зрения менее выгодны чем то что предлагается моими конкурентами я теряю деньги. Свои деньги. не знаю кому как а мне лично это не нравится. Гораздо, неизмеримо больше не нравится чем могут не наравиться любые фреймворки!
Мне не нужен ORM, я могу просто использовать SQL