Модераторы: LSD, AntonSaburov

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> hibernate пометить поле удалённым, но не удалять физически 
V
    Опции темы
Samotnik
Дата 30.4.2011, 15:50 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Super star !
****


Профиль
Группа: Awaiting Authorisation
Сообщений: 7192
Регистрация: 4.11.2006
Где: Минск City

Репутация: 5
Всего: 191



Привет smile
Есть приложение работающее с БД через хибер. Нужно, при удалении записей не удалять их физически из БД, а помечать как удаленные, для того чтобы в последующем, можно было делать запросы на удалённые записи.
Сделал это так: добавил в таблицы поле boolean deleted, по дефолту оно false, как только запись удаляется, я сеччу в это поле null, таким образом я избегаю unique constraint violated эксепшена, выглядит это так:
Код

@Entity
@Table(uniqueConstraints=@UniqueConstraint(columnNames={"name", "deleted"}))
public class Test { 
@Id
private long id;

@Column(nullable = false)
private String name;

private Boolean deleted = false;

//остальные поля
}


Всё отлично работало с MySQL, в БД спокойно ложились записи вида:
('test1', null)
('test1', null)
('test1', null)
('test1', null)
и т.д. 

Но вот беда, перешёл на Oracle, а там это не прокатывает, получается что там null == null если этот null в состовном ключе находится, и как следствие вылетает constraint violated эксепшен. 

Вопрос, что можно придумать в данной не простой ситуации, что можете подсказать или посоветовать smile  smile 
Как вариант, можно попробовать использовать envers, но может другие решения есть ?


Это сообщение отредактировал(а) Samotnik - 30.4.2011, 15:54
PM MAIL   Вверх
Старовъръ
Дата 30.4.2011, 16:01 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 491
Регистрация: 8.5.2008

Репутация: 1
Всего: 10



Зачем нужны Unique constraints на deleted?
PM MAIL WWW   Вверх
carper
Дата 3.5.2011, 08:18 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 227
Регистрация: 2.3.2005

Репутация: 2
Всего: 8



Цитата(Samotnik @  30.4.2011,  15:50 Найти цитируемый пост)
 только запись удаляется, я сеччу в это поле null


Null, строго говоря, не следует использовать как флаг, т.к. null - означает неопределенное состояние.

Поле - метка удаленной записи не должно нести на себе каких-то уникальных констрейнов, как вам сказал Старовъръ.

В сухом остатке - создайте boolean field named as DELETED default false, при удалении заносите туда true, а не null.
И поле не должно быть частью первичного ключа!
PM MAIL   Вверх
Samotnik
Дата 3.5.2011, 18:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Super star !
****


Профиль
Группа: Awaiting Authorisation
Сообщений: 7192
Регистрация: 4.11.2006
Где: Минск City

Репутация: 5
Всего: 191



Цитата(carper @  3.5.2011,  08:18 Найти цитируемый пост)
В сухом остатке - создайте boolean field named as DELETED default false, при удалении заносите туда true, а не null.
И поле не должно быть частью первичного ключа! 

Да, но как быть с уникальностью поля name в таком случае ? Их не должно быть более одного одинакового, если оно не помечено как deleted.

Добавлено через 12 минут и 30 секунд
Цитата(Старовъръ @  30.4.2011,  16:01 Найти цитируемый пост)
Зачем нужны Unique constraints на deleted? 

потому что в БД, не может быть создано более одного имени Nikolai, но удалено их может быть сколько угодно. Если не создать uniqueConstraints на поля "name", "deleted", то как по-другому уникальность реализовать ?

Это сообщение отредактировал(а) Samotnik - 3.5.2011, 18:48
PM MAIL   Вверх
Старовъръ
Дата 3.5.2011, 21:21 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 491
Регистрация: 8.5.2008

Репутация: 1
Всего: 10



Ну тогда располагай хотя бы true/false, а не true/null. Ну или в таком случае введи понятие версии, а не флажка. Если мы удалили или что-то изменили, то создается новая версия объекта с таким же ID и с инкременченной версией. Или может имеет смысл это хранить в каком-то архивном хранилище дабы не снижать производительность БД.

Это сообщение отредактировал(а) Старовъръ - 3.5.2011, 22:03
PM MAIL WWW   Вверх
Samotnik
Дата 4.5.2011, 00:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Super star !
****


Профиль
Группа: Awaiting Authorisation
Сообщений: 7192
Регистрация: 4.11.2006
Где: Минск City

Репутация: 5
Всего: 191



Старовъръ,  т.е. использовать envers ?

Это сообщение отредактировал(а) Samotnik - 4.5.2011, 00:33
PM MAIL   Вверх
carper
Дата 4.5.2011, 09:14 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 227
Регистрация: 2.3.2005

Репутация: 2
Всего: 8



Цитата(Samotnik @  3.5.2011,  18:48 Найти цитируемый пост)
Да, но как быть с уникальностью поля name в таком случае ? Их не должно быть более одного одинакового, если оно не помечено как deleted.


Введите ограничение на то, что поле name просто должно быть уникальным, независимо от того есть ли такое поле помеченное как "удаленное" или нет.  Т.к. иначе вы получаете сразу два Васи, отличающихся только тем, что один из них помечен как удаленный - спрашивается и какой из 2-х Васей в таком случае помечен?

Более того, поскольку у вас запись только помечена как удаленная, это автоматически предполагает, что вы можете передумать, тогда совсем уж глупо иметь двух Васей, отличающихся только признаком удаленной записи.

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

У вас 100% проблемы не с пометкой полей, а с архитектурой. В частности с первичными ключами.



P.S.
И причем тут  envers?  Вам таки нужна версионность и куча записей в архиве на каждого удаленного Васю?
Во-первых, это просто делается и без envers - просто введите соотв. поле, во-вторых, версионность для одного и того же Васи, скажем для адресов его проживания, совсем не одно и тоже, что и версионность для ряда совсем разных Вась, в последнем случае, это вообще чушь какая-то получится.  smile


P.P.S.
И наличие синтетического первичного ключа по ID в большинстве случаев совсем не освобождает от необходимости "человекопонимаемого" АК.


PM MAIL   Вверх
MisterCleric
Дата 4.5.2011, 10:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1043
Регистрация: 16.2.2006
Где: Харьков, Украина

Репутация: 33
Всего: 38



Привет всем.
Я делаю так:
При пометке записи как удаленная в те поля, которые должны быть уникальны, к существующему значению добавляю метку времени, а также проставляю статус как удаленная. 
Таким образом поле всегда уникально, избавляемся от композитный констрейнтов и ключей. А также такие записи всегда можно отфильтровать по like.
Естественно, что у меня заведомо длина поля больше чем, я предоставляю для ввода пользователем...


--------------------
ПРИШЕЛ, УВИДЕЛ - ПЕРЕПИСАЛ...
PM MAIL ICQ   Вверх
Samotnik
Дата 4.5.2011, 11:21 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Super star !
****


Профиль
Группа: Awaiting Authorisation
Сообщений: 7192
Регистрация: 4.11.2006
Где: Минск City

Репутация: 5
Всего: 191



Цитата(MisterCleric @  4.5.2011,  10:59 Найти цитируемый пост)
При пометке записи как удаленная в те поля, которые должны быть уникальны, к существующему значению добавляю метку времени, а также проставляю статус как удаленная. 
Таким образом поле всегда уникально, избавляемся от композитный констрейнтов и ключей.

не понимаю, как это можно сделать без композитных ключей ? Ведь поле name должно быть само по себе уникально, т.е. что бы пользователь не смог вставить запись Dima дважды  smile 
Поясни плиз. 
И вот это я совсем не понял:
Цитата(MisterCleric @  4.5.2011,  10:59 Найти цитируемый пост)
Естественно, что у меня заведомо длина поля больше чем, я предоставляю для ввода пользователем... 


PM MAIL   Вверх
MisterCleric
Дата 4.5.2011, 11:52 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1043
Регистрация: 16.2.2006
Где: Харьков, Украина

Репутация: 33
Всего: 38



Поясню на примере:
1. Было у нас в записи значение поля name Вася.
2. Я помечаю эту запись как удаленную.
3. Апдейчу поле name приблизительно так: 
Код

user.name += ' [' + new Date().time + ']


Благодаря тому, что время всегда идет вперед, пользователь никогда не сможет нарушить уникальность

Добавлено через 2 минуты и 10 секунд
И насчет композитный ключей: у тебя должно быть поле ID с генерируемым числовым значением - автоинкремент, сиквенс, или что там у тебя поддерживает БД


--------------------
ПРИШЕЛ, УВИДЕЛ - ПЕРЕПИСАЛ...
PM MAIL ICQ   Вверх
Samotnik
Дата 4.5.2011, 12:06 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Super star !
****


Профиль
Группа: Awaiting Authorisation
Сообщений: 7192
Регистрация: 4.11.2006
Где: Минск City

Репутация: 5
Всего: 191



MisterCleric, прикольно, эванокак smile 
А чем хуже, если объединить name и deleteTimeStamp в UniqueConstraint ? Вроде ж тоже уникальность будет. 

Цитата(MisterCleric @  4.5.2011,  11:52 Найти цитируемый пост)
И насчет композитный ключей: у тебя должно быть поле ID с генерируемым числовым значением - автоинкремент, сиквенс, или что там у тебя поддерживает БД 

С Id тут вообще целая история, он у меня вот так генерится:
Код

@Id
@GenericGenerator(name="customIdGenerator", strategy="CustomIdGenerator")
@GeneratedValue(strategy=GenerationType.TABLE, generator="customIdGenerator")
private long id;


где
Код

public class CustomIdGenerator extends TableGenerator {
    
    private static final Log logger = LogFactory.getLog(CustomIdGenerator.class);

    @Override
    public Serializable generate(SessionImplementor session, Object object)
            throws HibernateException {
        long id;
        try {
            id = (Long)object.getClass().getMethod("getId").invoke(object);
        } catch (Throwable t) {
            logger.fatal(t, t);
            return super.generate(session, object);
        }
        if (id > 0) {
            return id;
        } else {
            return super.generate(session, object);
        }
    }
}

Вроде так работает и для MySQL и для Oracle
PM MAIL   Вверх
MisterCleric
Дата 4.5.2011, 12:19 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1043
Регистрация: 16.2.2006
Где: Харьков, Украина

Репутация: 33
Всего: 38



Цитата

А чем хуже, если объединить name и deleteTimeStamp в UniqueConstraint ? Вроде ж тоже уникальность будет. 


Можно и так, но какое тогда у тебя будет там значение у "неудаленных" записей?
Ведь уже обсудили, что NULL не нормально использовать в уникальных констрейнтах

Добавлено через 1 минуту и 10 секунд
И по твоему генератору.
Какая тогда проблема?
Ведь поле name у тебя не участвует в PK записи.


--------------------
ПРИШЕЛ, УВИДЕЛ - ПЕРЕПИСАЛ...
PM MAIL ICQ   Вверх
Samotnik
Дата 4.5.2011, 13:10 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Super star !
****


Профиль
Группа: Awaiting Authorisation
Сообщений: 7192
Регистрация: 4.11.2006
Где: Минск City

Репутация: 5
Всего: 191



MisterCleric, ясно. А что делать, если есть сущности в которых уже есть композитные ключи, например:
Код

@Table(uniqueConstraints=@UniqueConstraint(columnNames={"subscriber_id", "message_id"}))
public class Delivery {

    @ManyToOne(fetch = FetchType.EAGER)
    @JoinColumn(name="message_id")
    private Message message;

    @ManyToOne(fetch = FetchType.EAGER)
    @JoinColumn(name="subscriber_id")
    private Subscriber subscriber;
//....
}

Как в таком случае ее помечать удалённой ?

Это сообщение отредактировал(а) Samotnik - 4.5.2011, 13:10
PM MAIL   Вверх
MisterCleric
Дата 4.5.2011, 14:08 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1043
Регистрация: 16.2.2006
Где: Харьков, Украина

Репутация: 33
Всего: 38



Но у тебя же здесь композитный ключ состоит из внешних ключей.
На что у тебя здесь идет уникальность? Где то бизнес-поле, которое требует уникальности?
У тебя же такая конкретна сущность относится к конкретным внешним сущностям. Если ты их помечаешь как удаленные эта тоже должна быть таковой.
Или у тебя эти внешние ключи неуникальны?


--------------------
ПРИШЕЛ, УВИДЕЛ - ПЕРЕПИСАЛ...
PM MAIL ICQ   Вверх
Samotnik
Дата 4.5.2011, 14:25 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Super star !
****


Профиль
Группа: Awaiting Authorisation
Сообщений: 7192
Регистрация: 4.11.2006
Где: Минск City

Репутация: 5
Всего: 191



MisterCleric, да, всё верно, спасибо, должно работать. 
Еще вопрос, генерить hashCode() и equals() лучше всего по id или uniqueConstraints или id + uniqueConstraints 
 smile 
PM MAIL   Вверх
MisterCleric
Дата 4.5.2011, 14:54 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1043
Регистрация: 16.2.2006
Где: Харьков, Украина

Репутация: 33
Всего: 38



Вообще советуют по какому-нибудь бизнес-ключу.
В твоем случае, наверное, uniqueConstraint достаточно. Но это, конечно, если оно у тебя всегда заполнено


--------------------
ПРИШЕЛ, УВИДЕЛ - ПЕРЕПИСАЛ...
PM MAIL ICQ   Вверх
Samotnik
Дата 4.5.2011, 15:54 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Super star !
****


Профиль
Группа: Awaiting Authorisation
Сообщений: 7192
Регистрация: 4.11.2006
Где: Минск City

Репутация: 5
Всего: 191



MisterCleric, понял, спасибо. На счет сущностей, которые связывают другие, всё же способ не работает:
Код

@Table(uniqueConstraints=@UniqueConstraint(columnNames={"device_id", "app_id"}))
public class Subscriber {
    
    @Id
    @GenericGenerator(name="customIdGenerator",
                      strategy="CustomIdGenerator")
    @GeneratedValue(strategy=GenerationType.TABLE, generator="customIdGenerator")
    private long id;

    @ManyToOne(fetch = FetchType.EAGER)
    @JoinColumn(name = "device_id")
    private Device device;

    @ManyToOne(fetch = FetchType.EAGER)
    @JoinColumn(name = "app_id")
    private App app;

        private Boolean deleted = false;

Создаю запись:
id, device_id, app_id, deleted
(1; 5; 9; false)
Удаляю
(1; 5; 9; true)
Создаю опять точно такую же - 
(2; 5; 9; false)
Цитата

java.sql.BatchUpdateException: Duplicate entry '5-9' for key 'device_id'

 smile 

Это сообщение отредактировал(а) Samotnik - 4.5.2011, 16:53
PM MAIL   Вверх
MisterCleric
Дата 4.5.2011, 16:24 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1043
Регистрация: 16.2.2006
Где: Харьков, Украина

Репутация: 33
Всего: 38



Не понял. Почему "Создаю такую же"?
Ведь это же новая запись: должен быть id новый.
Что у тебя за бардак такой?


--------------------
ПРИШЕЛ, УВИДЕЛ - ПЕРЕПИСАЛ...
PM MAIL ICQ   Вверх
Samotnik
Дата 4.5.2011, 16:54 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Super star !
****


Профиль
Группа: Awaiting Authorisation
Сообщений: 7192
Регистрация: 4.11.2006
Где: Минск City

Репутация: 5
Всего: 191



MisterCleric, да, извини не дописал, уже исправил, id конечно же новый. Но при чем он тут ? У меня уникальность стоит по полям device_id + app_id именно по этому я не могу создать нового subscriber если уже существует такой же удалённый.

Это сообщение отредактировал(а) Samotnik - 4.5.2011, 16:59
PM MAIL   Вверх
Samotnik
Дата 4.5.2011, 17:13 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Super star !
****


Профиль
Группа: Awaiting Authorisation
Сообщений: 7192
Регистрация: 4.11.2006
Где: Минск City

Репутация: 5
Всего: 191



Цитата(MisterCleric @  4.5.2011,  16:24 Найти цитируемый пост)
Что у тебя за бардак такой?

почему бардак smile
Вот представь, очень простой пример. Тебе дали задание разработать сущность "Пользователь" с двумя полями Имя, Фамилия. При условии, что нельзя создать двух одинаковых записей с одной именем + фамилией(например нельзя создать Дмитрий Петров дважды smile  )
Плюс предусмотреть сохранение удалённых пользователей, т.е. не удалять их физически из БД, а каким-либо образом помечать что они удалены и не мешали созданию новых полей (и их удаление) Т.е. БД должна себя вести, как будто этих записей нету в таблице. 
Это я релизовал с помощью флага deleted, путем выставления его в null при удалении записи. С MySQL всё превосходно работало, а вот с Oracle нет.    

PM MAIL   Вверх
MisterCleric
Дата 4.5.2011, 17:19 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1043
Регистрация: 16.2.2006
Где: Харьков, Украина

Репутация: 33
Всего: 38



Тогда добавь к этой уникальности еще и ID.
Или вообще убери эту уникальность на внешние ключи.
Не понимаю ее смысла.
У тебя что по логике нельзя создать несколько Subscriber на один и тот же Device в одном и том же App?
Да и вообще самый идеальный вариант - провести нормализацию: удаленные записи переносить в архивные таблицы.


--------------------
ПРИШЕЛ, УВИДЕЛ - ПЕРЕПИСАЛ...
PM MAIL ICQ   Вверх
Samotnik
Дата 4.5.2011, 17:55 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Super star !
****


Профиль
Группа: Awaiting Authorisation
Сообщений: 7192
Регистрация: 4.11.2006
Где: Минск City

Репутация: 5
Всего: 191



Цитата(MisterCleric @  4.5.2011,  17:19 Найти цитируемый пост)
Тогда добавь к этой уникальности еще и ID.

не вариант, тогда можно будет создавать Дмитрий Петров сколько угодно раз.
Цитата(MisterCleric @  4.5.2011,  17:19 Найти цитируемый пост)
Не понимаю ее смысла.

смысл в том, чтобы запретить создавать более одной записи Дмитрий Петров
Цитата(MisterCleric @  4.5.2011,  17:19 Найти цитируемый пост)
Да и вообще самый идеальный вариант - провести нормализацию: удаленные записи переносить в архивные таблицы.

а это как ? smile Можно ссылку или пример ?
Цитата(MisterCleric @  4.5.2011,  17:19 Найти цитируемый пост)
У тебя что по логике нельзя создать несколько Subscriber на один и тот же Device в одном и том же App?

нет, нельзя, а какой смысл создавать их несколько ?
Зачем столько записей ? Подписчик должен быть один.
id, device_id, app_id, deleted
(1; 5; 9)
(2; 5; 9)
(3; 5; 9)
(4; 5; 9)
(5; 5; 9)
(6; 5; 9)
....


Это сообщение отредактировал(а) Samotnik - 4.5.2011, 17:57
PM MAIL   Вверх
MisterCleric
Дата 4.5.2011, 18:05 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1043
Регистрация: 16.2.2006
Где: Харьков, Украина

Репутация: 33
Всего: 38



Не знаю таких ссылок, но на пальцах это так:
1. Копия оригинальной таблицы с префиксом ARC
2. Убираем констрейнты, окромя PK
3. Вызываем обычное удаление
4. В БД на удаление должен быть триггер на каждую таблицу
5. Он должен просто взять удаляемую запись и проинсертить в соответствующую архивную таблицу.
6. Потом ты сможешь эти записи доставать через named-query, а результат повесить на твою основную сущность.

Польза: разделяем данные по логике, повышается производительность на основной таблице.
Минусы: много работы на БД, написание named-query на удаленные записи.

Нужно здесь хорошенько подумать, стоит ли все данные оставлять: может будет нормальным, если какие-то связи все-таки будут удаляться навсегда?


--------------------
ПРИШЕЛ, УВИДЕЛ - ПЕРЕПИСАЛ...
PM MAIL ICQ   Вверх
Samotnik
Дата 5.5.2011, 12:23 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Super star !
****


Профиль
Группа: Awaiting Authorisation
Сообщений: 7192
Регистрация: 4.11.2006
Где: Минск City

Репутация: 5
Всего: 191



Цитата(MisterCleric @  4.5.2011,  18:05 Найти цитируемый пост)

4. В БД на удаление должен быть триггер на каждую таблицу

триггер - это ведь sql код. т.е. вручную нужно прописывать, а через хибер можно как-нибудь написать триггер ? 
PM MAIL   Вверх
Samotnik
Дата 6.5.2011, 16:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Super star !
****


Профиль
Группа: Awaiting Authorisation
Сообщений: 7192
Регистрация: 4.11.2006
Где: Минск City

Репутация: 5
Всего: 191



Если кому интересно, то проблема решилась как всегда - очень просто. 
Поле deleted - сделать типом long по дефолту = -1L, при удалении сетить в это поле тот id, который удаляется  smile

Добавлено через 6 минут и 7 секунд
Цитата(MisterCleric @  4.5.2011,  14:54 Найти цитируемый пост)
Вообще советуют по какому-нибудь бизнес-ключу.
В твоем случае, наверное, uniqueConstraint достаточно. Но это, конечно, если оно у тебя всегда заполнено

так может тогда лучше по id ? 
PM MAIL   Вверх
MisterCleric
Дата 6.5.2011, 16:30 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1043
Регистрация: 16.2.2006
Где: Харьков, Украина

Репутация: 33
Всего: 38



Привет. Решение красивое.
Сам додумался? 
Век живи - век учись...

По поводу equals & hashCode. 
У меня вот такой вот класс для всех сущностей:
Код

public abstract class BaseEntity<ID extends Serializable> implements Serializable {
    public abstract ID getId();

    public abstract void setId(ID id);

    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;

        BaseEntity other = (BaseEntity) o;

        if (getId() != null ? !getId().equals(other.getId()) : other.getId() != null) return false;

        return true;
    }

    public int hashCode() {
        return getId() != null ? getId().hashCode() : super.hashCode();
    }
}


Я, кажись, его тут уже на форуме выкладывал.
Он хорошо работает в рамках логики, которую пишу я. Но для самого Hibernate оно не годиться, так как тот у себя в коде использует класс org.hibernate.util.IdentityMap, который для hashCode вызывает System.identityHashCode, а для equals еще хуже - идет сравнение ссылок.



--------------------
ПРИШЕЛ, УВИДЕЛ - ПЕРЕПИСАЛ...
PM MAIL ICQ   Вверх
Samotnik
Дата 6.5.2011, 17:06 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Super star !
****


Профиль
Группа: Awaiting Authorisation
Сообщений: 7192
Регистрация: 4.11.2006
Где: Минск City

Репутация: 5
Всего: 191



спс
PM MAIL   Вверх
Страницы: (2) [Все] 1 2 
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Java"
LSD   AntonSaburov
powerOn   tux
  • Прежде, чем задать вопрос, прочтите это!
  • Книги по Java собираются здесь.
  • Документация и ресурсы по Java находятся здесь.
  • Используйте теги [code=java][/code] для подсветки кода. Используйтe чекбокс "транслит", если у Вас нет русских шрифтов.
  • Помечайте свой вопрос как решённый, если на него получен ответ. Ссылка "Пометить как решённый" находится над первым постом.
  • Действия модераторов можно обсудить здесь.
  • FAQ раздела лежит здесь.

Если Вам помогли, и атмосфера форума Вам понравилась, то заходите к нам чаще! С уважением, LSD, AntonSaburov, powerOn, tux.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Java EE (J2EE) и Spring | Следующая тема »


 




[ Время генерации скрипта: 0.1415 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.