![]() |
|
Модераторы: LSD, AntonSaburov |
![]()
|
|
| garbuz |
|
||||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 677 Регистрация: 22.1.2008 Репутация: 8 Всего: 11 |
Есть код, который достает из базы через хибернейт два оъекта - юзера и проджект. У проджекта есть коллекция юзеров. Перед добавление пользователя в проект, проверяю его наличие в этом проекте, хотя даже если такой пользователь имеется, то все равно происходит добавление.
Судя по дебаггеру, не срабатывает
У проджекта коллекция юзеров проинициализирована. Пробовал проверять объекты юзеров из проджекта на equals с текущим пользователем, тоже нифига не equals. В чем дело? Объекты разные получаются? У объектов поля одинаковые, хотя как у одного, так и у другого есть не проинициализированные поля. У энтити юзер нет ни метода hashCode ни equals. Может в них дело? Спасибо. |
||||
|
|||||
| Galaran |
|
|||
|
Шустрый ![]() Профиль Группа: Участник Сообщений: 91 Регистрация: 25.5.2009 Репутация: нет Всего: 2 |
contains не срабатывает, так как надо метод equals() переопределить у класса юзер, иначе оно использует equals() класса Object, который просто по ссылке сравнивает.
Когда будешь писать сравнение для юзеров, не наткнись на то, что я недавно напоролся. А именно, если id у тебя там Long (не long), и ты сравниваешь по нему, надо сначала взять значение у этих лонгов, иначе по ссылке будет. Примерно так:
|
|||
|
||||
| garbuz |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 677 Регистрация: 22.1.2008 Репутация: 8 Всего: 11 |
Парсер лохе! Первый раз не отправил мое сообщение
Galaran, спасибо за совет, так и думал сделать, однако вчера на это не хватило сил (5-ый час). Сделал сегодня - не работает. Дело в том, что при получении дочерней коллекции из объекта, вытащенного с пом хибернейт, мы получаем объект PersistentSet, где метод contains почему-то не работает. На это есть даже баг в джире http://opensource.atlassian.com/projects/h...browse/HHH-2634 и пара тем на форумах https://forum.hibernate.org/viewtopic.php?t=965543, https://forum.hibernate.org/viewtopic.php?t=928172, которые пока не прочитал
Думаю есть более красивое решение |
|||
|
||||
| MisterCleric |
|
|||
![]() Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1043 Регистрация: 16.2.2006 Где: Харьков, Украина Репутация: 33 Всего: 38 |
А какая версия hibernate? А то я как-то не задумывался о том, что они могут не работать и так все и сделал у себя как здесь описано (давно уже...). Взял переопределил методы equals & hashCode и все нормально работает на contains -------------------- ПРИШЕЛ, УВИДЕЛ - ПЕРЕПИСАЛ... |
|||
|
||||
| magicfly |
|
||||
|
Шустрый ![]() Профиль Группа: Участник Сообщений: 109 Регистрация: 21.2.2007 Репутация: 1 Всего: 1 |
Привет,
ну во первых можно использовать не обычный итератор а дженерик итератор, во вторых, не мешало бы переопределить и хеш код ( когда переопределяешь иквелс лучше сразу и переопределелять хеш код), в третьих небольшое замечание насчет сравнения лонгов как было написано
Проверил, PersistentSet есть Wrapper вокруг HashSet'a следовательно еще необходимо как было сказано переопределить HashCode Это сообщение отредактировал(а) magicfly - 28.9.2009, 16:59 |
||||
|
|||||
| Dims |
|
|||
![]() Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1016 Регистрация: 21.11.2006 Репутация: нет Всего: 11 |
Вообще-то, чтобы объекты правильно хранились в коллекции, в общем случае, нужно переопределять не только equals, но и hashCode.
Добавлено @ 16:48 Потому что, например, класс HashSet определяет расположение объектов по хэшкоду, то есть, сравнение хэшкодов используется как быстрая (но неточная) операция сравнения. И только когда хэшкоды совпали, при необходимости, вызывается медленная проверка с помощью equals. Возможно, в ваших функциях тоже где-то в глубине используется хэшкод. Вообще, есть, можно сказать правило: переопределил equals -- переопредели hashCode. Это сообщение отредактировал(а) Dims - 28.9.2009, 18:36 |
|||
|
||||
| garbuz |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 677 Регистрация: 22.1.2008 Репутация: 8 Всего: 11 |
Ок, домой приду - поробую переопределить hashCode. А может еще кто скажет как правильно его переопрделять? Мне собственно никогда не приходилось делать это. IDE сама генерит. На нее можно положиться?
|
|||
|
||||
| magicfly |
|
|||
|
Шустрый ![]() Профиль Группа: Участник Сообщений: 109 Регистрация: 21.2.2007 Репутация: 1 Всего: 1 |
http://www.geocities.com/technofundo/tech/.../equalhash.html
Смотря как она это делает. Грубо говоря ты (вы?) можешь использовать те поля по которым идет сравнение и для вычисления hashCode, т.е. равные объекты имеют одинаковый хеш код, разные -разный. Однако на больших массивах данных это не оптимально. Советую посмотреть как работают хеш коллекции для большего понимания. Насколько я помню это есть в "thinking in java" |
|||
|
||||
| Dims |
|
|||
![]() Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1016 Регистрация: 21.11.2006 Репутация: нет Всего: 11 |
Ну я обычно для составного объекта генерю хэшкод так: беру хэшкоды всех членов и произвожу над ними исключающее побитовое "или". Если это встроенный тип int, то я ксорю прямо его значение. Если другой, то сперва преобразую в ссылочный и беру его hashCode. Надо учитывать, что если хэшкод для объекта не переопределён, то это будет нечто вроде адреса в памяти, то есть, число отличающееся у идентичных, но разных объектов (например, у объекта и его клона). Поэтому может потребоваться переопределить хэшкоды для членов тоже. До абсурда доводить не надо. На каком-то уровне вполне может подойти стандартная функция от Обжекта. |
|||
|
||||
| garbuz |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 677 Регистрация: 22.1.2008 Репутация: 8 Всего: 11 |
Вот что выдала IDEA. Пойдет?
Проверил - работает! Всем спасибо за помощь |
|||
|
||||
| MisterCleric |
|
|||
![]() Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1043 Регистрация: 16.2.2006 Где: Харьков, Украина Репутация: 33 Всего: 38 |
Galaran,
Высказывание не верно: все обертки простых типов + String являются immutable: каждый раз создается новый объект. И говорит о том, что будет сравнение по ссылке не верное. У них как раз методы equals такие, что берутся на сравнеие их значение простых типов. посмотрите исходники -------------------- ПРИШЕЛ, УВИДЕЛ - ПЕРЕПИСАЛ... |
|||
|
||||
| magicfly |
|
||||
|
Шустрый ![]() Профиль Группа: Участник Сообщений: 109 Регистрация: 21.2.2007 Репутация: 1 Всего: 1 |
Хотелось бы заметить это не совсем правда.
вернет одинаковые ссылки т.е. i==j. И для Integer"ов до 128 ссылки тоже будут равны,т.е.
выведет true false |
||||
|
|||||
| Galaran |
|
|||
|
Шустрый ![]() Профиль Группа: Участник Сообщений: 91 Регистрация: 25.5.2009 Репутация: нет Всего: 2 |
я про это и говорю, что вначале следует взять значения, которые оборачиваются этими объектами и сравнить их
это оптимизация компилятора, верно? Это сообщение отредактировал(а) Galaran - 29.9.2009, 00:01 |
|||
|
||||
| MisterCleric |
|
||||||
![]() Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1043 Регистрация: 16.2.2006 Где: Харьков, Украина Репутация: 33 Всего: 38 |
А я как раз говорю о том, что не надо брать это значение, если используем метод equals, а не сравниваем их перегруженным для этого оператором "==" Вот пример метода класса Long
Мы обсуждаем метод equals, а не оптимизацию интерпретатора для констант по 128 -------------------- ПРИШЕЛ, УВИДЕЛ - ПЕРЕПИСАЛ... |
||||||
|
|||||||
| magicfly |
|
|||
|
Шустрый ![]() Профиль Группа: Участник Сообщений: 109 Регистрация: 21.2.2007 Репутация: 1 Всего: 1 |
Я лишь указал на промахи, в частности на
Из immutable не следует что каждый раз создается один объект и сравнение по ссылке временами бывает верным |
|||
|
||||
![]()
|
| Правила форума "Java" | |
|
|
Если Вам помогли, и атмосфера форума Вам понравилась, то заходите к нам чаще! С уважением, LSD, AntonSaburov, powerOn, tux. |
| 0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей) | |
| 0 Пользователей: | |
| « Предыдущая тема | Java EE (J2EE) и Spring | Следующая тема » |
|
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |