Кузин Мирослав @StackBook
Программирую здесь и сейчас
Information
- Rating
- 3,009-th
- Location
- Ростов-на-Дону, Ростовская обл., Россия
- Date of birth
- Registered
- Activity
Specialization
Backend Developer, Mobile Application Developer
Middle
Git
Python
PostgreSQL
Spring Boot
Apache Kafka
Java
Docker
Кайфовая статья!
Наши веб-браузеры тоже по сути же мобильные приложухи. Интересно, например, в Яндекс браузере сработает сей трюк? 🤔
И работает ли это с PWA приложениями?
Этот вариант самый первый в статье со схожим выводом.
Спасибо вам, за то, что несколько расширили данный сценарий примерами, как можно обойти использование сетов для сущностей в императивном стиле.
Также чуть дополню. Когда нам нужно одну огромную коллекцию отфильтровать по другой, можно ещё отдельное множество под айдишники завести и в цикле по сущностям вызывать contains. Сам пользуюсь, кайфую.
Сами сеты на самом деле нормально можно использовать во многом только для многие ко многим и один ко многим, поскольку в том же хибере и ряде ORM есть оптимизация при генерации запросов. Для этих целей сеты даже с вырожденным hashCode прекрасно работают (ибо под капотом там тоже самое дерево получается), сам на работе применяю и все летает, кода мало.
Поскольку композиция, когда дочерняя сущность не может существовать без родительской
В том то и дело, проблема стандартна и сложна. Для связей с композицией так не работает. Должна быть единая точка сохранения родителя и ребенка и она в вашей версии будет писаться вручную, а не использовать готовые варианты, которые просты и реализуются банально быстрее, что для типового приложения важнее.
Это история про компромиссы, нельзя усидеть на всех стульях сразу.
Ваш вариант можно и точно где-то нужно брать на вооружение, но за своей простотой он требует глубокого понимания кода и понимание, что везде так делать наоборот неэффективно.
Вы возможно и имеете понимание, что серебрянной пули не существует, но имеет ли его типовой разработчик?
Спасибо за ваш вариант, добавил упоминание о вашей версии.
Здесь я с вами отчасти соглашусь, но тогда связи один ко многим и многие ко многим, к сожалению, превращаются в бойлерплейт код и ограничивают возможности ORM фреймворков.
Вы правы, возможно на грубость и не тянет.
Для меня это воспринимается как: "Лучше бы не писал статью" и возможно это только мои проблемы.
При той же подготовке, вообще нигде нет полного анализа всех вариантов реализации. Что всех, хотя бы основных. Многие пишут абстракто: "Не делай так". А вопрос, как тогда? Описанные выше проблемы магическим образом не решаться, если я не буду писать так)
Поэтому и есть это статья, как попытка показать как надо и где именно.
Касаемо кэша, кто вообще в эпоху кубера и децентрализованных приложений делает кэш в оперативной памяти для сущностей?)
Да и примеров 7, в 3 из которых нет описанной вами проблемы.
Честно говоря не понимаю ваших возмущений.
Статья начинается со слова "ЛучшИЕ", выбирайте любой по ситуации. Сами ситуации описаны.
Соглашусь с вами, что контекст повествования может быть запутанным и мне нужно поработать над этим, но пожалуйста не грубите. Нелогично и против всех правил, которые вы не приводите это как минимум конструктивно. А сами правила и вправду есть и это вторая ссылка в источниках в статье).
Спасибо за ваш отзыв
В начале статьи я подмечаю, что объекты по сути делятся на два типа: модели и сущности. Модели сравниваем по всем полям, они неизменяемые.
И у меня черным по белому(или наоборот 🤔) написано про сравнение сущностей! Касаемо вырожденного варианта по логике это не только для JPA, а для всего, что может генерировать первичный ключ на стороне базы, а это почти внезапно все ORM для всех языков.
Даже без ORM, если мы отделяем слой того же репозитория и работаем именно как с изменяемымм объектами у нас будут сущности и у нас может возникать перерасчёт хэша при изменении поля id.
Да, в идеальном мире у определения сущность, должен быть уникальный идентификатор неизменяемый, но пригенерации в базе это можно достичь только одним путем - натуральный идентификатор. И тут либо JPA и почти все ORM с изащренной идеологией, либо DDD. Тут каждый выбирает для себя сам! Я лишь провел свой анализ и поделился своим мнением.
В целом это то можно избегать (изменяемый id) и использовать либо модели(те же проекции к ним относятся), либо генерацию ключа на стороне приложения и я об этом также написал!
Я нигде не возводил свой вариант как эталон для всего и в самой статье рекомендую использовать именно натуральный идентификатор по возможности для тех же именно сущностей.
Собачки с котиками как раз, чтобы доходчиво показать, что это проблема не только хибера и JPA, а любого сравнения изменяемых объектов!
А кто работает с хибером, все об знают)
Если бы...
Создаётся впечатление, что вы поверхносто пробежали статью. Если это не так, подскажите, что именно вам было не понятно? Или может быть какие-то мои фразы сбили столку?
Хорошее замечание, меня тоже это во многом смущало, однако в вариантах от Jpa Buddy /Amplicode и джава чемпиона тоже самое)
На это высказался и провел свои замеры Vlad Mihalcea здесь: https://vladmihalcea.com/how-to-implement-equals-and-hashcode-using-the-jpa-entity-identifier/
Как показывает практика, сложные операции в любом случае лучше делать на стороне базы данных, а для относительно небольших коллекций все также быстро работает, как и показано в тестах с contains.
Если у вас есть вариант получше, я с удовольствием приму его на вооружение.
Повторюсь, для нормализации схемы.
Учите биологию, кошки подкласс млекопитающих)
TypeAnimal его определяет.
Да, можно сделать много уровней наследования, но если сущности будут SQL ориентированы, то возникнут трудности.
Я больше руководствуюсь структурной типизацией, если в той же функции будет это свойство, утка будет рада))
Касаемо реализации в потомке, выдает такую же ошибку, как и у Вас в примере при создании экземпляра Dog.
Зависит от задач. Если мы работаем с аналитикой, может быть куча таблиц, где операции самые стандартные. Тогда удобно использовать ORM и набор базовых операций.
Если компоненты системы во-многих поведенческий моментах отличаются, лучше писать как Вы предлагаете.
Можно сделать и свойством класса. Это лишь один из вариантов нормализации схемы.
В последних примерах как раз таки показывается применение простых функций, объединенных логически в модули. Для модулей можно сделать протоколы, если необходимо иметь абстракции. В ходе статьи я и вел к тому, что можно использовать модули и в базовых слоях с ними будет работать проще.
За видео спасибо, гляну как будет время.
Понравился второй вариант, переписал похожим образом, только без ClassVar)
Прислушался к Вашим замечаниям и малость переписал примеры.
TypeAnimal, name_type согласен, в контексте примера лишнее, мыслил ограничением значений на уровне базы. Поменял на enum)
В общем, я понял, что Вы имеете ввиду. Да, если мы пробрасываем репозиторий в сервис, то в сервисе содержится поле с ним и это его состояние. И для адаптеров получится тоже самое. Однако stateless это про "состояние независимость" и поэтому говориться мной про синглтон. Если Вам удобнее внедрять зависимость через классы, дело Ваше, однако моя задача была показать иной способ и да, я верю и знаю что для слоев адаптер, сервис и репозиторий в случае python практически всегда проще использовать модули без классов, об этом и статья была по-большому счету.
Да, это сделано намерено. Иначе в CrudService можно было бы написать полноценный метод.
Подключений к бд да, скорее всего будет несколько, тот же редис для хэширования.
Состояние у сервиса, оно быть может, а может и не быть.
У нас разное понимание stateless класса. В этом основное различие)
Бизнес данные меняются в основном только в бд. Запросами я не меняю поля того же sessionManager, поэтому он и будет глобальным и это уже как правило базовый класс. Объекта репозитория мне хватит и одного на все приложение, поскольку его функции не меняют свое поведение от изменения его полей. Это я и понимаю про stateless. Если учитывать базу, то у нас и слой адаптеров не будет stateless, поскольку тот же delete, post запрос будет вести себя не как чистая функция (особенно если id генерируется).
К SQL да, возможно слишком много акцента.