Сравнение классов-сущностей БД - по id или по всем полям?
От:
Аноним
Дата:
30.03.10 19:58
Оценка:
Привет! Дано: классы, представляющие различные типы сущностей, все классы в конечном итоге мапятся на строки в таблицах БД. Каждый класс имеет id и набор полей, специфичных для типа сущности.
В таблицах id суть суррогатный ключ.
Вопрос: каким образом лучше реализовать их сравнение (метод equals(), в случае Java)?
Сравнивать только id. Встаёт вопрос — как быть с ситуациями, когда id равны, а остальные поля нет?
Сравнивать все поля (представляется предпочтительным).
Мнения приветствуются!
... А>Вопрос: каким образом лучше реализовать их сравнение (метод equals(), в случае Java)?
А> А>Сравнивать только id. Встаёт вопрос — как быть с ситуациями, когда id равны, а остальные поля нет? А>Сравнивать все поля (представляется предпочтительным). А>
А>Мнения приветствуются!
Это сильно зависит от того, для чего нужно сравнивать и какой из вариантов будет нужен чаще. Тот что чаще будет использоваться лучше занести в equal, другой в Comparator.
equal можно реализовать в базовом классе путем сравнения id. Если какой-то сущности понадобится сравнить больше полей, то можно рассмотреть переопределения equal. Опять все зависит от специфики задач.
Не припоминаю в своей практике, где понадобилось бы сравнение всех полей.
Re: Сравнение классов-сущностей БД - по id или по всем полям
Здравствуйте, Аноним, Вы писали:
А>Привет! А>Дано: классы, представляющие различные типы сущностей, все классы в конечном итоге мапятся на строки в таблицах БД. Каждый класс имеет id и набор полей, специфичных для типа сущности. А>В таблицах id суть суррогатный ключ.
А>Вопрос: каким образом лучше реализовать их сравнение (метод equals(), в случае Java)?
А> А>Сравнивать только id. Встаёт вопрос — как быть с ситуациями, когда id равны, а остальные поля нет? А>Сравнивать все поля (представляется предпочтительным). А>
В общем случае по primary key. Если у вас id равны, а поля разные, значит сущность изменило свое состояние. Например, пользователь загрузил Person из БД и поменял Person.name.
Проблема в сравнении по PK в том, что id может быть еще не установлен. Например, пользователь добавляет несколько Person в приложении и имеет возможность их менять. Сохранение происходит при нажатие кнопку "save", а не сразу после добавления. Тогда имеет смысл сравнивать так: if (id = NO_ENTITY_ID) { return equlasByFields() } else {return equalsById()}.
PS Пока писал, сообразил, что проще во втором случае делать id < 0 (например, а в БД строго > 0) и все равно сравнивать только по PK.
Здравствуйте, Аноним, Вы писали:
А>Вопрос: каким образом лучше реализовать их сравнение (метод equals(), в случае Java)?
А> А>Сравнивать только id. Встаёт вопрос — как быть с ситуациями, когда id равны, а остальные поля нет? А>Сравнивать все поля (представляется предпочтительным). А>
А>Мнения приветствуются!
А с какой целью их сравнивать?
Пишу под .net сравниваю только данные, не относящиеся к первичному ключу,
а так же ключи и ссылки на экземпляры (ReferenceEquals).
У меня в софтине не может существовать более одного экземпляра сущности с одинаковыми ключами,
нигде и ни у кого, ибо это предусмотрено архитектурой.
Всё сказанное выше — личное мнение, если не указано обратное.
Re: Сравнение классов-сущностей БД - по id или по всем полям
А мнение такое: не допускать существования двух и более сущностей с одинаковыми ключами.
Решается это или методом Create репозитория, который генерит Id сущности, обращаясь к БД за новым уникальным идентификатором,
либо GUID для Id (если экземпляры сущностей создаются строго на клиенте).
На опушке за околицей мужики строили коровник.
Работали споро и весело. Получалось х**во.
Re[2]: Сравнение классов-сущностей БД - по id или по всем по
От:
Аноним
Дата:
31.03.10 08:49
Оценка:
Здравствуйте, LeonidV, Вы писали:
LV>Проблема в сравнении по PK в том, что id может быть еще не установлен. Например, пользователь добавляет несколько Person в приложении и имеет возможность их менять. Сохранение происходит при нажатие кнопку "save", а не сразу после добавления. Тогда имеет смысл сравнивать так: if (id = NO_ENTITY_ID) { return equlasByFields() } else {return equalsById()}.
У меня PK — сгенерированный UID, так что пустым быть не может.
А может, имеет смысл вообще выкинуть выделенный кусок, и всегда сравнивать по ID? А то, на мой взгляд, не комильфо будет, когда два объекта были равны до сохранения в базу, а после перестали (не исключено, что там даже контракт equals нарушится, поскольку без изменения значащих полей у нас equals стал возвращать другое значение для тех же объектов).
Re[3]: Сравнение классов-сущностей БД - по id или по всем по
Здравствуйте, Аноним, Вы писали:
А>У меня PK — сгенерированный UID, так что пустым быть не может. А>А может, имеет смысл вообще выкинуть выделенный кусок, и всегда сравнивать по ID? А то, на мой взгляд, не комильфо будет, когда два объекта были равны до сохранения в базу, а после перестали (не исключено, что там даже контракт equals нарушится, поскольку без изменения значащих полей у нас equals стал возвращать другое значение для тех же объектов).
Я так и написал в PS. Два объекта если равно до сохранения в БД, то скорее всего они и пожизни равны. Хотя всякое бывает. Если просто убрать, не озаботившись о разных идентификаторах не сохраненных объектов, то получится, что все объекты равны, даже если у них поля разные.
Здравствуйте, Аноним, Вы писали:
А>Привет! А>Дано: классы, представляющие различные типы сущностей, все классы в конечном итоге мапятся на строки в таблицах БД. Каждый класс имеет id и набор полей, специфичных для типа сущности. А>В таблицах id суть суррогатный ключ.
А>Вопрос: каким образом лучше реализовать их сравнение (метод equals(), в случае Java)?
А> А>Сравнивать только id. Встаёт вопрос — как быть с ситуациями, когда id равны, а остальные поля нет? А>Сравнивать все поля (представляется предпочтительным). А>
А>Мнения приветствуются!
Есть несколько типов сравнения:
1. Сравнение ссылок: в .NET — ReferenceEquals, в других — сравнение ссылок. Собственно, показывает, что две переменных ссылаются на один и тот же объект.
Является достаточным условием равенства. Если вы используете ОРМ, который поддерживает Identity mapping — одной строчке таблицы всегда будет соответствовать один экземпляр.
2. Сравнение по первичному ключу и типу: является необходимым и достаточным условием того, что два объекта содержат данные из одной строки таблицы.
Это условие может нарушаться, если таблица самостоятельно генерирует ключи для записей.
3. Сравнение по значению всех полей и типу. Если первичный ключ хранится как часть данных объекта, то равенство полей объекта будет автоматически означать выполнение условия 2.
А для чего вам вообще понадобилось сравнение?
There is no such thing as the perfect design.
Re: Сравнение классов-сущностей БД - по id или по всем полям
Здравствуйте, Аноним, Вы писали:
А>Вопрос: каким образом лучше реализовать их сравнение (метод equals(), в случае Java)?
В общем случае сравнивать только первичный ключ. Вы написали ID — но это частный случай первичного ключа. Иногда первичный ключ будет состоять из двух-трех полей.
А>[list=1] А>Сравнивать только id. Встаёт вопрос — как быть с ситуациями, когда id равны, а остальные поля нет?
Такие ситуации будут скорее всего означать что вы не используете паттерн Identity Map (ничего в принципе страшного) и что у вас нашлись две версии объекта и одна из них более новая/измененная. Что делать в такой таком случае зависит от конкретной ситуации — приведите ситуацию — рассмотрим. Главное не допускать изменения первичного ключа у объекта, т.е. поля/свойства входящие в первичный ключ должны быть неизменяемыми.