Search
Write a publication
Pull to refresh
2
1.1
Кузин Мирослав @StackBook

Программирую здесь и сейчас

Send message

Кайфовая статья!

Наши веб-браузеры тоже по сути же мобильные приложухи. Интересно, например, в Яндекс браузере сработает сей трюк? 🤔

И работает ли это с 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 да, возможно слишком много акцента.

1

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