|
|
|
Правильный подход с реализацией equals/hashCode ?
|
|||
|---|---|---|---|
|
#18+
Каждый раз натыкаюсь на этот вопрос и до сих пор не выработал для себя правильного (идеального) подхода. Итак, речь идёт о доменных объектах, которые хранятся в БД, имеют первичный ключ и набор атрибутов. Первичный ключ генерирует БД при вставке объекта. Никакого уникального неизменного атрибута сущность не имеет. Как правильнее реализовать equals/hashCode? Известные недостатки в известных подходах: 1. Использовать id. Плохо тем, что до момента вставки в БД id ещё не определён. 2. Использовать все атрибуты, кроме id. Плохо тем, что на протяжении жизни объекта значения атрибутов могут измениться и соответственно изменится результат работы equals/hashCode. Это нарушает контракт данных методов и потенциально ведёт к проблемам в runtime. 3. Использовать искусственный уникальный неизменяемый атрибут. Плохо тем, что нужно этот атрибут явно определить, задавать значение и хранить в БД Может есть более красивые подходы? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 12.11.2014, 14:19 |
|
||
|
Правильный подход с реализацией equals/hashCode ?
|
|||
|---|---|---|---|
|
#18+
junixar1. Использовать id. Плохо тем, что до момента вставки в БД id ещё не определён. equals() определяет предикат равенства двух объектов на уровне логики вашего приложения. В него вовсе не обязан входить Id. В него даже не обязаны входить все поля. Это вопрос смысла а не шаблона или подхода. Два физ-лица когда равны? Когда равны два платежа? Еще раз. Смотрите в корень. В логику. По hashCode() - что говорить. Возьмите исходники JDK. Посмотрите как он уже реализован для String, Date, java.awt.Dimention, Long. Если непонятно - спрашивайте. Поясню. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 12.11.2014, 14:32 |
|
||
|
Правильный подход с реализацией equals/hashCode ?
|
|||
|---|---|---|---|
|
#18+
junixar1. Использовать id. Плохо тем, что до момента вставки в БД id ещё не определён. Определяйте. UUID, например. Реально поможет много где. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 12.11.2014, 14:37 |
|
||
|
Правильный подход с реализацией equals/hashCode ?
|
|||
|---|---|---|---|
|
#18+
junixar1. Использовать id. Плохо тем, что до момента вставки в БД id ещё не определён. Ну, как вариант использовать натуральный ключ. Важно только на него констрейнт в базе иметь. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 12.11.2014, 14:38 |
|
||
|
Правильный подход с реализацией equals/hashCode ?
|
|||
|---|---|---|---|
|
#18+
junixarМожет есть более красивые подходы? - попробовать ничего не делать)) Как раз хибер имеет доп.атрибут - версия. И сам обеспечивает изоляцию объектов между сессиями авторобъект=строка_в_БД_на_основе_PK ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 12.11.2014, 15:03 |
|
||
|
Правильный подход с реализацией equals/hashCode ?
|
|||
|---|---|---|---|
|
#18+
junixar, А как насчет: Код: java 1. 2. 3. 4. 5. 6. 7. 8. 9. ? Ну и сделать соответствующий hashcode. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 12.11.2014, 15:03 |
|
||
|
Правильный подход с реализацией equals/hashCode ?
|
|||
|---|---|---|---|
|
#18+
БД вовсе не обязывает иметь таблицы с PK. Яркий пример - logging tables, staging tables, temporary tables. Я сам с позиции сторонника правильной реляционной алгебры с этим не согласен но по факту в продуктивных системах таких таблиц много. И их существование имеет свои аргументы. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 12.11.2014, 15:05 |
|
||
|
Правильный подход с реализацией equals/hashCode ?
|
|||
|---|---|---|---|
|
#18+
mayton, не вижу, зачем такой гемор? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 12.11.2014, 15:07 |
|
||
|
Правильный подход с реализацией equals/hashCode ?
|
|||
|---|---|---|---|
|
#18+
Что не видишь? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 12.11.2014, 15:12 |
|
||
|
Правильный подход с реализацией equals/hashCode ?
|
|||
|---|---|---|---|
|
#18+
mayton, зачем в продуктиве табличка без PK). Ну, если, окромя это свалка лога в виде кучи записей. Тогда это - off ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 12.11.2014, 15:15 |
|
||
|
Правильный подход с реализацией equals/hashCode ?
|
|||
|---|---|---|---|
|
#18+
Petro123, я приведу просто - типичные DDL скриптики.и Типпичный лог Код: plsql 1. Типичная загрузка. Таблица - одноразовая. Создаётся только для заливки из внешних источников. Потом грохается. Код: plsql 1. И зачем здесь PK ? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 12.11.2014, 15:21 |
|
||
|
Правильный подход с реализацией equals/hashCode ?
|
|||
|---|---|---|---|
|
#18+
mayton, imho - тут не нужен. Для ТС и сабжа - нужен. Тогда и вопрос ТС отпадёт сам собой. ) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 12.11.2014, 15:30 |
|
||
|
Правильный подход с реализацией equals/hashCode ?
|
|||
|---|---|---|---|
|
#18+
Автор пишет что до момента вставки в БД, id еще не определён. Это от скудности опыта. Я не знаю какой стек технологий он использует но в Oracle, генерация суррогатных ПК никак не связана со вставкой. Вы получаете его значение как Sequence_name.nextval и оно 100% уникально в рамках системы. Дальше - используете его как хотите. Вставляйте сразу ID, а потом обновляйте филды или вставляйте вместе. Вобщем либерально. А про хибернейты меньше надо читать. Они только портят общее понимание как работает БД. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 12.11.2014, 15:44 |
|
||
|
Правильный подход с реализацией equals/hashCode ?
|
|||
|---|---|---|---|
|
#18+
Petro123зачем в продуктиве табличка без PK). Ну если админы смотрят на тебя сурово и говорят "какой суррогатный ключ? Ты что, охренел? Лярд записей и у каждой суррогатный ключ? Удалить! Что за индекс на три поля? Что значит PK хочется? Обойдись двумя, нафиг уникальность". Вот и получается, что у таблицы нет первичного ключа... PS: взаимоотношение адми-прогер какое уж есть. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 12.11.2014, 15:45 |
|
||
|
Правильный подход с реализацией equals/hashCode ?
|
|||
|---|---|---|---|
|
#18+
Томин выступил несколько утрированно но в целом верно. Программист не кодит сферические вещи в вакууме. Каждая хотелка имеет свою цену и перед тем как ее создать надо посчитать сколько под нее купить винчестерОв-процессорОв-стриммерОв... e.t.c. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 12.11.2014, 15:49 |
|
||
|
Правильный подход с реализацией equals/hashCode ?
|
|||
|---|---|---|---|
|
#18+
Если нет PK, не понятно, как запись идентифицировать. При delete например Пример с таблицей логов лично для меня не показатель. Если таймп стемп не может повторяться - он пк, если может, быстро подряд сформировавшиеся сообщения могут быть прочитаны в другом порядке - получаем не лог, а охинею. Т.ч. я бы тоже туда ID или номер по порядку добавил бы. Я в целом, если без ПК живете хорошо - ну живите, мешать не буду. Но для меня таблица без ПК как-то нонсенс ))) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 12.11.2014, 15:56 |
|
||
|
Правильный подход с реализацией equals/hashCode ?
|
|||
|---|---|---|---|
|
#18+
Leonid KudryavtsevЕсли нет PK, не понятно, как запись идентифицировать. коротко - никак)) ... PL Developer, жмём кнопку - Редактировать - пишет: "Добавьте в запрос поле rowid иначе не смогу" )) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 12.11.2014, 16:00 |
|
||
|
Правильный подход с реализацией equals/hashCode ?
|
|||
|---|---|---|---|
|
#18+
При просмотре событий во времени обычно не стоит задачи идентификации "точки" на оси времени. Время как мы с вами помним из курса физики - величина непрерывная. Берут обычно интервал. Например от текущего времени и до суток назад. И спокойно смотрят события с order-by ts. А точность TIMESTAMP задаётся до 10 знаков после запятой. Как вы понимаете трудно создать процесс который генерит события дважды за 0.0000000001 s. Вопрос добавления доп. ключа типа sequence к timestamp для меня остаётся открытым. Я не знаю зачем мне нужен и какую пользу я получаю от этого. Вобщем это лучше обсудить с Ораклоидами . Накидают больше советов чем я. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 12.11.2014, 16:13 |
|
||
|
Правильный подход с реализацией equals/hashCode ?
|
|||
|---|---|---|---|
|
#18+
maytonА точность TIMESTAMP задаётся до 10 знаков после запятой. Как вы понимаете трудно создать процесс который генерит события дважды за 0.0000000001 s.... Это если Вы поштучно в таблицу добавляете А пусть у Вас на логе затык, и я хочу лог накапливать в своем буффере и потом в базу кидать одним bulk insert? Если код на Java, C то сгенерить соседние записи лога быстрее, чем например оттикает currentTimeMillis - легко. А в целом, просто личные привычки. Спорить не буду. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 12.11.2014, 16:39 |
|
||
|
Правильный подход с реализацией equals/hashCode ?
|
|||
|---|---|---|---|
|
#18+
И не спорь. Просто расскажи что тебе даст второй суррогат ID в данном кейсе. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 12.11.2014, 16:46 |
|
||
|
Правильный подход с реализацией equals/hashCode ?
|
|||
|---|---|---|---|
|
#18+
maytonИ не спорь. Просто расскажи что тебе даст второй суррогат ID в данном кейсе. хотя бы order by что бы лог читать в том же порядке, в котором я его генерил (принимаем, что поле timestamp может быть не уникальное. Пусть по причине кривых рук разработчика log'а) Если, же, поле timestamp уникально, то тогда уверять, что в данной таблицы "нет PK" странно ))) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 12.11.2014, 16:50 |
|
||
|
Правильный подход с реализацией equals/hashCode ?
|
|||
|---|---|---|---|
|
#18+
maytonА точность TIMESTAMP задаётся до 10 знаков после запятой. Как вы понимаете трудно создать процесс который генерит события дважды за 0.0000000001 s. System.nanoTime() :This method provides nanosecond precision, but not necessarily nanosecond resolution (that is, how frequently the value changes)С десятью знаками timestamp - тоже самое. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 12.11.2014, 16:50 |
|
||
|
Правильный подход с реализацией equals/hashCode ?
|
|||
|---|---|---|---|
|
#18+
maytonequals() определяет предикат равенства двух объектов на уровне логики вашего приложения. В него вовсе не обязан входить Id. В него даже не обязаны входить все поля. Это вопрос смысла а не шаблона или подхода. Два физ-лица когда равны? Когда равны два платежа? Если вы поместите физ.лицо в Map, а затем у физ. лица изменится хотя бы один атрибут, входящий в equals, то вы его потом просто не найдёте. Уникальных несуррогатных атрибутов у физ. лица нет. Хотя бы потому, что любой атрибут мог быть вбит оператором неправильно и потребует корректировки оператором. maytonЕще раз. Смотрите в корень. В логику. Хорошо. Куда именно то смотреть? Явного уникального несуррогатного атрибута нет. И? maytonПо hashCode() - что говорить. Возьмите исходники JDK. Посмотрите как он уже реализован для String, Date, java.awt.Dimention, Long. Если непонятно - спрашивайте. Поясню. Много раз видел, как он там реализован. Пояснений не требуется. Только по контракту значение hashCode не может изменяться за время жизни объекта. И что дальше? Какие атрибуты использовать для hashCode у физ. лица? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 12.11.2014, 16:53 |
|
||
|
Правильный подход с реализацией equals/hashCode ?
|
|||
|---|---|---|---|
|
#18+
maytonТиппичный лог Код: plsql 1. В многопользовательской системе, хорошо бы как-то по user'ам / или на крайняк процессам-сессиям разделять А то если два пользователя одновременно работать будет - такая помойка получится ))) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 12.11.2014, 16:56 |
|
||
|
Правильный подход с реализацией equals/hashCode ?
|
|||
|---|---|---|---|
|
#18+
Leonid KudryavtsevmaytonИ не спорь. Просто расскажи что тебе даст второй суррогат ID в данном кейсе. хотя бы order by что бы лог читать в том же порядке, в котором я его генерил (принимаем, что поле timestamp может быть не уникальное. Пусть по причине кривых рук разработчика log'а) Если, же, поле timestamp уникально, то тогда уверять, что в данной таблицы "нет PK" странно ))) Не забывайте что речь идёт о самом банальном логе. Мы не фиксируем туда bulk-операции в порядке поступления ВСЕХ данных. Мы не агрегируем логи с облака серверов. Мы не накапливаем гигабитный трафик пакетов. Мы просто фиксируем чортовы события. Юзер залогонился. Юзер оплатил счёт. Вышел. Как в 99.9% системах. Если у вас действительно есть постановка в которой происходит тот ужас который я перечислил то это не является логом. И к нему моя схема - неприменима. Вот как-то в таком вот аспекте. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 12.11.2014, 16:58 |
|
||
|
Правильный подход с реализацией equals/hashCode ?
|
|||
|---|---|---|---|
|
#18+
maytonАвтор пишет что до момента вставки в БД, id еще не определён. Это от скудности опыта. Я не знаю какой стек технологий он использует но в Oracle, генерация суррогатных ПК никак не связана со вставкой. Вы получаете его значение как Sequence_name.nextval и оно 100% уникально в рамках системы. Дальше - используете его как хотите. Вставляйте сразу ID, а потом обновляйте филды или вставляйте вместе. Вобщем либерально. Вам конечно виднее про мой опыт. В логике системы я создаю множество объектов. И далеко не факт, что эти объекты будут в итоге сохранены в БД. И дёргать БД только для того, чтобы получить id объекта, который возможно не будет сохранён в БД - на мой взгляд странно. Да, объект получит свой id из sequence в момент вставки в БД. maytonА про хибернейты меньше надо читать. Они только портят общее понимание как работает БД. Это из разряда - "..., но осуждаю"? Не имеет значения какой стэк в моём случае используется. Будь то голый JDBC или одна из ряда ORM. К вопросу это не имеет отношения. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 12.11.2014, 17:00 |
|
||
|
Правильный подход с реализацией equals/hashCode ?
|
|||
|---|---|---|---|
|
#18+
Leonid KudryavtsevmaytonТиппичный лог Код: plsql 1. В многопользовательской системе, хорошо бы как-то по user'ам / или на крайняк процессам-сессиям разделять А то если два пользователя одновременно работать будет - такая помойка получится ))) Да это просто пример. Семантика event VARCHAR2(255) может быть вполне осмысленная. И с юзером и с сессией. У меня есть свой log4j appender. С кольцевым буфером. С опциями расширенных Layouts. Там это всё есть. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 12.11.2014, 17:02 |
|
||
|
Правильный подход с реализацией equals/hashCode ?
|
|||
|---|---|---|---|
|
#18+
Не претендую на истинность в последней инстанции, но у нас на проекте Hiubernate сразу же ID выдавал (вроде через newEntity() создавали). Правда там все было сложно: Hibernate -> Cobol -> Oracle. В детали реализации старались не лезть, что бы не пугаться. 1. Использовать id. Плохо тем, что до момента вставки в БД id ещё не определён. AFAIK Например MS Visual FoxPro при оптимистической блокировке, до момента вставки выдает ROWNUM -1, -2, -3 etc... В момент физического Insert'а ROWNUM становится реальным. В Oracle Forms мы просто запрашивали очередной ID из сиквенса. Сиквенс большой, его не жалко. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 12.11.2014, 17:03 |
|
||
|
Правильный подход с реализацией equals/hashCode ?
|
|||
|---|---|---|---|
|
#18+
У базы и файла есть принципиальная разница: данные в упорядочены в порядке поступления Для СУБД это не гарантируется. Соответственно, если чтение логов требует или предполагает знание порядка поступления записей от приложения, то этот порядок должен обеспечиваться суррогатным первичным ключом. Механизм генерации такого ключа - последовательности. P.S. Да, "почти одновременные" log(message) из разных процессов могут попасть в файл протокола в более-менее произвольном порядке. Но после записи - этот порядок будет фиксирован. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 12.11.2014, 17:04 |
|
||
|
Правильный подход с реализацией equals/hashCode ?
|
|||
|---|---|---|---|
|
#18+
maytonА точность TIMESTAMP задаётся до 10 знаков после запятой. Как вы понимаете трудно создать процесс который генерит события дважды за 0.0000000001 s. Вопрос добавления доп. ключа типа sequence к timestamp для меня остаётся открытым. Я не знаю зачем мне нужен и какую пользу я получаю от этого. Вобщем это лучше обсудить с Ораклоидами . Накидают больше советов чем я. Как многие понимают, создать процесс который генерит множество событий за 0.0000000001 s. - очень легко. Про точность TIMESTAMP тоже очень спорно, зависит от конкретной платформы. Ещё небольшое уточнение - почему Вы всегда упоминаете здесь Oracle? В посте ни слова про него не было. От богатства опыта? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 12.11.2014, 17:07 |
|
||
|
Правильный подход с реализацией equals/hashCode ?
|
|||
|---|---|---|---|
|
#18+
maytonНе забывайте что речь идёт о самом банальном логе. Мы не фиксируем туда bulk-операции в порядке поступления ВСЕХ данных. Мы не агрегируем логи с облака серверов. Мы не накапливаем гигабитный трафик пакетов. Мы просто фиксируем чортовы события. Юзер залогонился. Юзер оплатил счёт. Вышел. Как в 99.9% системах. Если у вас действительно есть постановка в которой происходит тот ужас который я перечислил то это не является логом. И к нему моя схема - неприменима. Вот как-то в таком вот аспекте. С таким "банальным" подходом можно и вообще ничего не логгировать. Сколько приходилось анализировать логи в production, когда система реально работает и множество пользователей чего-то делают и делается ещё много чего между разными системами и много чего делается асинхронно - всегда время записи в лог, порядок записи - были критически важны. И всегда было важно, чтобы время было синхронизировано на всех серверах системы. А теперь оказывается это и не лог вовсе в Вашем понимании. Чувствуется большой опыт. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 12.11.2014, 17:13 |
|
||
|
Правильный подход с реализацией equals/hashCode ?
|
|||
|---|---|---|---|
|
#18+
junixarЕщё небольшое уточнение - почему Вы всегда упоминаете здесь Oracle? В посте ни слова про него не было. От богатства опыта? Это верно. Мои примеры особенно с лог-табличкой с опциями interval partitioning (специально не писал ибо многобукв) - Oracle-технологичны. Однако если кто-то приведёт другой пример в плоскости Java - буду рад. Меня справедливо обвиняют в оффтопике. Забыл что тема - Java - сорри. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 12.11.2014, 17:17 |
|
||
|
Правильный подход с реализацией equals/hashCode ?
|
|||
|---|---|---|---|
|
#18+
junixar... maytonА про хибернейты меньше надо читать. Они только портят общее понимание как работает БД. Это из разряда - "..., но осуждаю"? Не имеет значения какой стэк в моём случае используется. Будь то голый JDBC или одна из ряда ORM. К вопросу это не имеет отношения. Мне кажется тут mayton прав У Вас получается все скомкано в одну кучу. И объекты, и база. Отсюда и проблемы. Термин "время жизни объекта" он же тоже не абсолютный, а от контекста зависит. Добавили объект в БД, старый грохнули, новый создали ))) Вот Вам и "по контракту значение hashCode не может изменяться за время жизни объекта" обеспечено. В данном случае, Вы пытаетесь скрестить ежа (контракты Java рассчитанные на работу с объектами в памяти) с удавом (базой данных, пусть реалиционную, да еще и с поддержкой транзакций). Получаете сто метров колючей проволоки. IMHO & AFAIK ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 12.11.2014, 17:19 |
|
||
|
Правильный подход с реализацией equals/hashCode ?
|
|||
|---|---|---|---|
|
#18+
Leonid Kudryavtsevjunixar... пропущено... Это из разряда - "..., но осуждаю"? Не имеет значения какой стэк в моём случае используется. Будь то голый JDBC или одна из ряда ORM. К вопросу это не имеет отношения. Мне кажется тут mayton прав У Вас получается все скомкано в одну кучу. И объекты, и база. Отсюда и проблемы. Термин "время жизни объекта" он же тоже не абсолютный, а от контекста зависит. Добавили объект в БД, старый грохнули, новый создали ))) Вот Вам и "по контракту значение hashCode не может изменяться за время жизни объекта" обеспечено. В данном случае, Вы пытаетесь скрестить ежа (контракты Java рассчитанные на работу с объектами в памяти) с удавом (базой данных, пусть реалиционную, да еще и с поддержкой транзакций). Получаете сто метров колючей проволоки. IMHO & AFAIK +1 ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 12.11.2014, 17:23 |
|
||
|
Правильный подход с реализацией equals/hashCode ?
|
|||
|---|---|---|---|
|
#18+
Petro123Leonid Kudryavtsevпропущено... Мне кажется тут mayton прав У Вас получается все скомкано в одну кучу. И объекты, и база. Отсюда и проблемы. Термин "время жизни объекта" он же тоже не абсолютный, а от контекста зависит. Добавили объект в БД, старый грохнули, новый создали ))) Вот Вам и "по контракту значение hashCode не может изменяться за время жизни объекта" обеспечено. В данном случае, Вы пытаетесь скрестить ежа (контракты Java рассчитанные на работу с объектами в памяти) с удавом (базой данных, пусть реалиционную, да еще и с поддержкой транзакций). Получаете сто метров колючей проволоки. IMHO & AFAIK +1 Объясняю: в вопросе были указаны условия, в которых собственно сам вопрос ставится. Я не просил обсуждать эти условия, стэк технологий или мой опыт. Теперь повторюсь: сущности не имеют явного уникального неизменяемого поля. Ид (первичный ключ) генерируется в момент вставки записи в БД. И это здесь не обсуждается. Это исходные условия. Вопрос - как лучше реализовать пару equals/hashCode ? Пока из всего обсуждения я вижу только одно решение - ввести суррогатное уникальное поле в сущность и заполнять значение поля в момент создания нового объекта. Данное поле соответственно сохранять в БД и там навесить условие уникальности на него. В общем-то понятно и логично - на мой взгляд. Других вариантов не вижу. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 12.11.2014, 17:33 |
|
||
|
Правильный подход с реализацией equals/hashCode ?
|
|||
|---|---|---|---|
|
#18+
... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 12.11.2014, 17:36 |
|
||
|
Правильный подход с реализацией equals/hashCode ?
|
|||
|---|---|---|---|
|
#18+
ты начал с этого junixarКаждый раз натыкаюсь на этот вопрос и до сих пор не выработал для себя правильного (идеального) подхода. Верный подход: - PK в табличке - время жизни об-та равно времени сессии - не выводить объекты из сессии хибера - не работать руками с ID объекта. Теперь давай код, если что не выходит по этим п.п. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 12.11.2014, 17:39 |
|
||
|
Правильный подход с реализацией equals/hashCode ?
|
|||
|---|---|---|---|
|
#18+
я бы представил такую аналогию: junixarЕсли вы поместите физ.лицо в Map, а затем у физ. лица изменится хотя бы один атрибут, входящий в equals, то вы его потом просто не найдёте. Уникальных несуррогатных атрибутов у физ. лица нет. Хотя бы потому, что любой атрибут мог быть вбит оператором неправильно и потребует корректировки оператором. 1. Есть бизнес объект реального мира. Марья Ивановна. Она родилась в 1951 году и умрет в 2017 ))) Это ее "время жизни" Она живет в квартире, иногда ходит на кладбище навестить могилу своей матери. Которая когда то умерла. Но жить на кладбище она категорически отказывается ))) 2. Есть электронное представление этого объекта реального мира в виде экземпляра объекта в памяти Java Machine. 3. Есть представление этого же объекта в СУБД с поддержкой транзакций Если мы говорим о СУБД с поддержкой транзакций, то как минимум, у нас будет 3-и больших "периода времени жизни". У объектов hibernate все по другому, я говорю с точки зрения СУБД 3.1. Данные введены но не переданы в СУБД 3.2. Данные переданы в СУБД но commit не выполнен (команда post) 3.3. Commit выполнен СУБД, как Вы понимаете, на время жизни экземпляра объекта в памяти JVM и "контракты" глубоко наплевать. Но и объекты, с точки зрения прикладной системы и бизнес логики, при этих трех состояниях совершенно разные. Как живая Марья Ивановна и ее уже покойная мама. И заставлять жить разные экземпляры Java отображающим объекты СУБД в этих разных состояниях в одном HashMap'е - как заставлять реальную Марью Ивановну жить на кладбище с ее бабушкой. Иногда (например в интерфейс при вводе новых данных) - приходится. Отображаем и реальную информацию из БД и новую, фейковую, которую оператор только еще вводит с клавиатуры. Но тогда, некий фейковый ключ (в FoxPro -1,-2,-3 etc) вполне может спасти. Ввод закончился. Фейковый объект попал в БД, стал реальным. ВСЕ. Это уже другой объект. Марья Ивановна тоже когда-то 9 месяцев в животе своей матери жила, но к ее паспортным данным сейчас это не имеет никакого значения и никого не интересует. Лирическое отступление по поводу относительности "времени жизни" и соответственно незыблемости "контрактов на время жизни объекта" junixarТеперь повторюсь: сущности не имеют явного уникального неизменяемого поля. Ид (первичный ключ) генерируется в момент вставки записи в БД. И это здесь не обсуждается. Это исходные условия. Вы ошибаетесь! Сущность Марья Ивановна неизменяемый пол имеет. Нет... конечно... кто сейчас Евровидение выигрывает всем известно... но Марья Ивановна не такая! У нее сиски 4-ого размера, отпечатки пальцев и много других уникальных характеристик. Только... подозреваю... Вы не об этом ))) Вот. Как-то так. Отделяя вечное - СИСЬКИ. От переходящего - хибернайт и база данных ))) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 12.11.2014, 17:52 |
|
||
|
Правильный подход с реализацией equals/hashCode ?
|
|||
|---|---|---|---|
|
#18+
maytonТомин выступил несколько утрированно но в целом верно. Какой утрировано. Это цитаты практически. Включая уровень аргументов и стиль общения :( Leonid KudryavtsevЕсли нет PK, не понятно, как запись идентифицировать. При delete например ... Я в целом, если без ПК живете хорошо - ну живите, мешать не буду. Но для меня таблица без ПК как-то нонсенс ))) Надо различать PK с точки зрения БД и реальный PK, который может быть. Например в той таблице - там есть три поля, которые дают уникальность. Что позволяет и удалять записи, и написать equals/hash. Просто в БД нельзя создавать ни уникальный индекс (хотя это скорее тараканы админов), ни PK. А использовать timestamp в качестве PK нельзя. Никак. Мало ли что. Есть UUID и этого достаточно. Либо sequence какой-нибудь, главное сначала брать его из БД, присваивать его новому объекту и жить с ним. Генерировать ID при записи- это не очевидный, но гарантированный, путь к проблемам потом, когда менять что-то будет уже лень. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 13.11.2014, 09:40 |
|
||
|
Правильный подход с реализацией equals/hashCode ?
|
|||
|---|---|---|---|
|
#18+
junixarТеперь повторюсь: сущности не имеют явного уникального неизменяемого поля. Ид (первичный ключ) генерируется в момент вставки записи в БД. И это здесь не обсуждается. Это исходные условия. У твоей машины нет одного колеса. Это не обсуждается, это исходные условия, чинить не будем. Но ехать до Казани надо. Подскажи, что делать? Генерация ID в момент вставки- это архитектурная ошибка. Она НЕ ИСПРАВЛЯЕТСЯ нормально НИКАКИМИ средствами. junixarВопрос - как лучше реализовать пару equals/hashCode ? Пока из всего обсуждения я вижу только одно решение - ввести суррогатное уникальное поле в сущность и заполнять значение поля в момент создания нового объекта. Данное поле соответственно сохранять в БД и там навесить условие уникальности на него. В общем-то понятно и логично - на мой взгляд. Других вариантов не вижу. Зря. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 13.11.2014, 09:44 |
|
||
|
Правильный подход с реализацией equals/hashCode ?
|
|||
|---|---|---|---|
|
#18+
Alexey TominНу если админы смотрят на тебя сурово и говорят Был такой анекдот в СССР про то, почему на Красной площади сексом не занимаются... ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 13.11.2014, 09:58 |
|
||
|
Правильный подход с реализацией equals/hashCode ?
|
|||
|---|---|---|---|
|
#18+
Сергей Арсеньев, А да забыл on-topic Про equals - хорошо написал mayton в первом же коменте. hashCode должен соответствовать двум требованиям 1. Если два экземпляра класса equals, то и hashCode equals. 2. Вычисление hashCode не должно быть медленнее equals (в идеале гораздо быстрее). Совсем идеальный hashCode обеспечивает равномерное распределение количества объектов по своим значениям. :) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 13.11.2014, 10:04 |
|
||
|
Правильный подход с реализацией equals/hashCode ?
|
|||
|---|---|---|---|
|
#18+
junixarЕсли вы поместите физ.лицо в Map, а затем у физ. лица изменится хотя бы один атрибут, входящий в equals, то это другое Физ лицо. :) Вы случайно не путаете с вопросом про текучесть HashMap при изменяющемся экземпляре ключа? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 13.11.2014, 10:11 |
|
||
|
|

start [/forum/topic.php?all=1&fid=59&tid=2126277]: |
0ms |
get settings: |
10ms |
get forum list: |
15ms |
check forum access: |
3ms |
check topic access: |
3ms |
track hit: |
341ms |
get topic data: |
9ms |
get forum data: |
2ms |
get page messages: |
77ms |
get tp. blocked users: |
1ms |
| others: | 203ms |
| total: | 664ms |

| 0 / 0 |
