Мани — часть апи с большим количеством логики
Давайте называть это всё таки классом.
Правильно ли я понимаю, что мы сейчас сравниваем «процедуры + структуры» vs «классы + JPA» и оба предпочитаем второе?
Увы, из-за засилья POJO неочевидно, что в Address конечно же появится логика.
Но есть запрос, который хочет сразу часть графа. Зачем тянуть основную сущность, делая дофига лейзи-инициализаций, если можно создать частичную view-сущность со всеми нужными полями игер? Альтернатива — написание большого jpql-запроса с куче JOIN FETCH.
EntityGraph?
И откуда всё таки хибернейт.инишлайз(), если строятся дто-шки?
Тогда с точки зрения джавы equals() равен ==, а JPA добавляет id.
Имел в виду основной принцип, который иллюстрировал — не привязываться к JPA. Если сущность в принципе не содержит данных, суть которых позволяет считать их хоть скольконибудь уникальными, то equals() является ==. Переходим на JPA, добавляем PK, неважно Long или uuid, он один начинает фигурировать в equals().
Uuid-ами не пользовался, но идея нравится.
про хобота с хибовскими сиквенсами
Хибернейтовскими?! Я думал, мы про сиквенс из БД говорим. Там, правда, тоже есть нюансы. Мы о каких хоботах?
При желании генерацию ууида можно вынести из хиба.
Я вначале подумал, что генерация уудда в конструкторе. Иначе невозможно сравнивать transient и persisted объекты. Впрочем, вы избегаете таких ситуацих в бизнес логике.
Поиск по произвольным полям.
Имел в виду такой сценарий. Тот же Client с произвольным поиском по firstName и/или lastName и т.д. Если в него ранее включен List<Order>
с eager, это его замедлит.
client.getPersonalData().getName();
client.getPersonalData().getSurName();
Если в client содержится разнообразная информация о клиенте, то именно так и имеет смысл группировать.
Хотите закрыть остальной объект оставив поля мутабельными?
Поинт в том, что возможно лучше не мутабельные поля, а бизнес методы модификаторы?
Давайте продолжать на примере Money. Имхо, класс лучше двух произвольно модифицируемых полей.
Не фанат спринг дата жпа, кстати. С ентитиМенеджером както приятнее еси честно. Но это персонально мои тараканы.
Из двух зол всегда можно выбрать третье — QueryDSL
Базовый мой пойнт в том, что еквалс по ид не является плохим решением. Тем более когда сущность, например, в принципе не содержит данных, суть которых позволяет считать их хоть скольконибудь уникальными.
Да, против практики не попрешь. Тогда с точки зрения джавы equals() равен ==, а JPA добавляет id.
Возможно, это причина пересмотреть саму структуру данных, выраженных в сущности и исключить поле, вызывающее тяжелый запрос, из сущности вообще, а для связи использовать новую сущность, которая мапится на ту же таблицу, но предназначена для конкретного сценария. Фактически, view-версия.
Не одобряю такое решение. Создаются две сущности, копи-паст либо «наследование». Зачем вообще исключать? Потому что то поле аннотировано eager, а менять на lazy — опасно?
Я вообще не сталкивался с ситуацией, когда Н+1 проблема.
Поиск по произвольным полям. CriteriaBuilder с like-ами. Хочется, чтобы он работал максимально быстро. А если у выдаваемой сущности есть eager поля или коллекции?
Спасибо за отклик!
Якщо є Dto, то весь граф буде завантажений у будь-якому випадку: чи то одним запитом, чи то подслідовними.
А как же инкапсуляция? Я специально привел примеры Address и особенно Money
Спасибо за развёрнутый коментарий.
В остальных случаях бизнес-равенство является более сложным понятием, оно определяется конкретной потребностью и для него пишется отдельный компаратор или несколько.
С этим, конечно, сложно спорить.
Помимо этого, как вы смотрите на то, что бизнес-логика очень часто должна позволять хранить бизнес-дубликаты в коллекциях? Вам нужны в коллекциях разные объекты которые еквалс друг другу? Точно?
А из-за этого, мне кажется, массово используется List вместо Set. Что в свою очередь приводит к невозможности отличить элементы в Cartesian product.
Развесили вы по всем бест-практисам лейзи лоадинга, все вроде красиво. Но тут у вас есть запрос который чтото достает, и отдает в жсон.
Json аннотации прямо на entity? Или есть Dto?
Я не порицаю лейзи лоадинг, мне просто не нравится тиражируемое заблуждение «лейзи = силвербуллет, игер = сжечьеретика», которая сквозит в большинстве статей про хиб/жпа.
Это не совсем так. Зависит, внезапно, бадум-тссс от того, какие у вас сценарии работы с сущностями. Неожиданно, да? :)
Я не хотел бы, чтобы меня приняли за фанатика lazy, но как быть, если eager устраивал до поры до времени, а потом внезапно появляется сценарий где эти данные не нужны, а их выборка тормозит запрос?
Н+1 не является такой уж серьезной проблемой. Более того, на практике он неизбежен.
Без конкрентного сценария и замеров невозможно сказать, насколько серьёзна проблема.
Спасибо.
Да, обычно структура БД уже есть и в своей практике не припомню с ней каких-то особых проблем. А вот как её потом в entities «дизассемблировать» — тут самое веселье и начинается.
Например: в каких-то таблицах есть createdBy, createdOn, modifiedBy, modifiedOn. Почему их выносят в супер-класс? Почему не композиция с @Embeddable?
Навіщо писати EAGER?
По-нормальному зробити не вийде, одночасно можуть бути сценарії, коли треба діставати вкладені колекції і коли ці дані не потрібні
Нехорошо, да. DataSource Proxy типа github.com/ttddyy/datasource-proxy в помощь
Если я бы мог вернуться в прошлое и учесть ваши замечания, то у статьи был бы более подходящий заголовок, но увы.
По поводу собеседований у меня другая статья о наболевшем, буду рад комментариям.
Я понимаю вашу претензию к интервьюерам и могу уверить, что сам не такой :-)
Тем не менее, считаю, что изменение требований, что в работе, что (с некоторыми упрощениями) на собеседовании — это обычная ситуация и держаться до последнего за наследование и template method не стОит.
Элжайл и импэкт маппинги — за рамками дискуссии.
Не так. Как умел, пытался проиллюстрировать мысль, что не надо спешить выносить общую функциональность в базовый класс. Наследование — это сильная связь, а требования всегда меняются, да.
Про HTTP в статье ни слова.
Билдер тоже не причём.
Мы используем у себя бумажный — несколько склеенных листов А1 с таблицей, что каждая команда к какой дате принесет. Каждая команда на стикерах пишет свои основные фичи, риски, проблемы, вопросы и клеит их на эту бумажную доску. Потом ленточками проводит, где кто зависит друг от друга.
Разверните, пожалуйста, более подробно, как происходит обработка этих данных. Потому что фото в статье выглядит, конечно, впечатляюще, но оставляет вопросы. Что произойдёт, если какие-то стикеры отклеятся и упадут на пол? Кто разбирает чужой почерк? Насколько понятно для других команд можно описать фичу, риск, проблему, вопрос на стикере? Что будет, если ошибочно проведут ленточку?
Даже если предположить наличие диджитала — окей, мы имеем достаточно сложный граф с большим количеством узлов. Кто и как его распутывает?
Буду благодарен за пояснения
Предлагаете ждать НГ, чтобы протестировать метод?!
Повторю свой старый комментарий.
Мне кажется, что все эти разговоры, что нет времени, денег, тестировщиков, одобрения заказчика etc писать тесты — это симптомы. Тесты не пишутся, потому что их слишком сложно или вообще невозможно написать. А причина — плохая компоновка кода. Даже если просто держать в уме «а как я этот метод буду тестировать?» — это уже очень сильно помогает. И Arrange-Act-Assert не должен особо выходить за рамки трёх строчек.
Если это не так, то не с тестом проблема, а сигнал, что код плохой.
Причём даже довольно короткий и простой. Чтобы не быть голословным, приведу пример
public void congrats() { Date today = new Date(); if (today.getMonth() == 1 && today.getDay() == 1) { System.out.println("Happy New Year!"); } }
Здесь ошибка. И она не в том, что не использован Calendar, а в том, что непонятно, как этот метод протестировать. И если исправлять баг, то, опять же, нет уверенности, что исправление верное. Главная проблема в сигнатуре метода, компоновке класса, а меньшая — что реализация подкачала.
Несколько сложно дать дельные советы в статье, рассчитаной на общую аудиторию. Я могу сказать на своём примере «Вот я был ментором у таких-то товарищей. И теперь они мидлы/синьоры». И объяснить как это произошло — пару лет ревьюил их код. Только вряд ли этот комментарий чем-то тщательнее статьи.
Дтошка строится вне сессии?