Pull to refresh

Comments 25

Spring Data или сам Hibernate могут быть достаточно умны, что бы поместить из в так называемый Bath и отдать их в СУБД за один раз, но для этого id новых записей надо знать за ранее, вот тут то и вступает в игру тот самый автоинкремент, запросив текущее значение счетчика, не трудно догадаться какие id будут у всех пяти записей.

  1. "Bath" переводится на русский как "ванна". Скорее всего, вы имели в виду слово "batch".

  2. "за ранее" -> "заранее"

  3. На самом деле "догадаться" очень трудно, потому что в общем случае СУБД обслуживает несколько коннектов одновременно, и в момент когда несколько сессий запросят несколько значений из sequence, каждая из них может получить монотонно нарастающий набор пересекающихся значений. Например, сессия 1 получит "1, 2, 5, 6" и сессия 2 получит "3, 4, 7, 8".

    Дальше не стал читать, сорри.

Благодарю за конструктивную критику. Опечатки поправлю.

Не вникая глубока в детали, скажу что желательно всегда использовать двухсторонние, если вы конечно на 100 % уверены что обратная связи вам

Я опешу самые явные случаи.

И тд. Если абстрагироваться от диалекта "рускага езыка")), то статья понравилась. Пишите еще, но вычитывайте, пожалуйста.

Ну это моя первая статья, хотя я старался. Буду улучшаться, в любом случае спасибо за отзыв.

Есть онлайн проверка на грамматику. Просто перед публикацией прогоняйте текст. За статью спасибо.

  1. MayToOne и OneToOne по умолчанию EAGER -> ManyToOne и OneToOne по умолчанию EAGER

  2. решении есть одно проблема -> решении есть однa проблема

Избегайте использования @Data и @ToString аннотаций Lombok. Обе эти аннотации использую все поля объектов по умолчанию, что может послужить причиной проблем.

Отличное замечание, но я так и не понял почему именно не стоит использовать @Data.

Буду благодарен, если объясните

@Data по умолчанию использует все поля объекта в equals и hashcode, отсюда и корень проблем. Самая очевидная из них это инициализация Lazy полей при вызове этих методов. Менее очевидная, это мутирующее поля из-за которых hashcode может меняться, это чревато тем что в какой-то момент вы можете не найти объект в коллекции несмотря на то что он там есть.

так а если есть необходимость использовать все поля для equals и hashcode?
например, сущность не имеет связей и коллекций. все равно плохо?

Если сущность, о которой Вы говорите, не хранится в коллекциях типа Set, например в качестве связи "многие к одному", то в принципе проблем не должно возникнуть.

например, сущность не имеет связей и коллекций. все равно плохо?

Всё равно плохо. Кто-нибудь обязательно положит сущности в коллекцию и добавит связи. Вас в этот момент может уже не быть на проекте. А те кто остался словят всяких неожиданных багов.


так а если есть необходимость использовать все поля для equals и hashcode?

А как возникнет такая необходимость, если сущность не хранится в коллекциях? Для чего это может понадобиться?

Stackoverfor будет при сериализации ещё. Когда json будешь делать, чтоб на фронт отдать)

Как вы знаете в Hibernate существуют два типа отношений между сущностями, оно и двустороннее. Не вникая глубока в детали, скажу что желательно всегда использовать двустороннее, если вы конечно на 100 % уверены что обратная связи вам никогда не понадобится то и одностороннее сойдет. Разница между ними не сильно большая (если все сделать грамотно), а пользы гораздо больше от двусторонней.

Я бы здесь все таки добавил ссылку на теорию реляционных баз данных. Просто в последние годы я вижу все больше и больше молодых программистов, которые "благодаря" Hibernate не знают и не понимают реляционные СУБД. Печальное зрелище. Добавив такую ссылку вы дадите этим людям хоть мизерный, но шанс, стать настоящими инженерами.

Обсалютно согласен с Вами, это минус всех фреймворков за "магией" каторых теряется реальный мир. И особенно это отражается на молодых специалистах. Но все же, я надеюсь на их пытливый ум.

спасибо за статью , топ. на граматику пофигу

 не трудно догадаться какие id будут у всех пяти записей.

Тут проблема безопасности, так как не только вам нетрудно догадаться.

Используйте UUID как идентификатор.

@Id

String id;

Кроме этого, использование последовательностей не посзволяет создавать сущности сразу в валидном состоянии.

Используйте UUID как идентификатор.
String id;

Так UUID или String ?

Да все равно, мне больше нравится UUID.toString() - более human readable когда в базе и логах смотришь .

А какая альтернатива у UUID.toString()? Что вам нравится меньше?

Как это все равно? UUID гораздо меньше, чем его toString. Если не стоит какая-то высшая цель, зачем просто так увеличивать размер объекта?

Проблема безопасности решается авторизацией. Даже есть пользователь попытается подставить id своего "соседа", он все равно не получит данных если вы позаботитесь о безопасности.

"Свои данные" и данные "соседа" это самый простой частный случай. Профиль, посты, комменты - там где можно сказать чьи данные.

В реальности же доменная модель бывает гораздо сложнее, разные пользователи могут управлять одними и теми же данными.

Хорошо реализованная система ACL - это сложно и дорого.

Поэтому приемлимой альтернативой к "хакеры нашли проблему в авторизации и увидели больше чем положено инкрементируя id" является "хакеры нашли проблему в авторизации но ничего не увидели потому что не смогли подобрать UUID"

А это уже аргумент! Благодарю за комент.

Параметризованные запросы

Ой, я думал, что при работе с хибером никто уже не использует параметры с цифрами и знаками вопроса. Это какой-то рудимент из Jdbc. Есть же более удобный вариант

session.createQuery("SELECT u FROM User WHERE u.name = :name")
   .setParameter("name", name)

Sign up to leave a comment.

Articles