удаление без удаления в hibernate
От: strcpy Россия  
Дата: 24.10.12 08:32
Оценка:
Привет!

Нужно сделать так, чтобы удаленные записи не выкашивались из базы данных, чтобы потом можно было без возни с бэкапом посмотреть что случилось. Можно вот такую схему провернуть:

@Entity
@Where(clause = "deleted <> 1")
@Table(name = "X")
@SQLDelete(sql = "UPDATE X SET deleted = '1' WHERE id = ?")
public class X {
// внутри описание столбца deleted
}


Это вроде работает. Но еще хочется добавить к каждой записи ссылку на журнал history, в котором бы была, скажем дата создания (она же дата удаления, если запись удаленная). Тут начинается проблема. Если я описываю внутри класса History ссылку на любой объект (я хочу чтобы history был у всех)

    Object entity;
    @Column(name = "ENTITY")
    @OneToOne
    Object getEntity(){
        return entity;
    }


то hibernate начинает ругаться, что мол нужен конкретный экземпляр, а не Object. Это в общем-то логично. Выделять общего предка у всех "неудаляемых" объектов мне не очень хочется, потому что в таком случае, насколько я понимаю, в SQL либо будет одна таблица с диким количеством столбцов, либо одна дополнительная общая таблица. Это не очень подходит, т.к. база данных будет дополнительно читаться с помощью SQL, и это все усложнит. Можно ли подключить history через поле object_id, внутри которого указана сущность в виде "X.12341", где x -- название сущности?

Может быть есть какие-то другие решения этой задачи? Более изящное решение?
Удвой число ошибок, если не получается добиться цели.
Re: удаление без удаления в hibernate
От: Аноним  
Дата: 24.10.12 10:22
Оценка: +1
Здравствуйте, strcpy, Вы писали:

S>Может быть есть какие-то другие решения этой задачи? Более изящное решение?


Триггер БД?
Re: удаление без удаления в hibernate
От: relgames  
Дата: 24.10.12 10:32
Оценка:
Здравствуйте, strcpy, Вы писали:

S>то hibernate начинает ругаться, что мол нужен конкретный экземпляр, а не Object. Это в общем-то логично. Выделять общего предка у всех "неудаляемых" объектов мне не очень хочется


Сделайте общего предка у History, и конкретные экземпляры — Entity1History, Entity2History и т.д. Это можно представить в БД в виде 1 таблицы со множеством полей.
Еще можно сделать один History, но завести поле type, куда писать тип объекта. Ну и в поле key — первичный ключ. Но тогда ссылки на объекты придется расставлять самому.
Punk Not Dead
Re: удаление без удаления в hibernate
От: Blazkowicz Россия  
Дата: 24.10.12 10:45
Оценка: +2
Здравствуйте, strcpy,

S>Нужно сделать так, чтобы удаленные записи не выкашивались из базы данных, чтобы потом можно было без возни с бэкапом посмотреть что случилось. Можно вот такую схему провернуть:

Подход к решению немного странный. Если ты решил таки оставлять записи, то, вероятно, для того чтобы позже где-то читать. Решение с флагом не очень хорошее по той причине что это флаг придется тянуть по всему проекту. Как, например, на счет отчетов?
Ты как бы пишешь "всегда читать только deleted=false", но при этом иногда когда очень надо читать и "deleted=true".
Мне кажется интересной была бы идея вынести часть реализации на базу. Удаленные записи переносить в отдельный сегмент по триггеру, например. Либо сделать View для только акутальных записей и читать оттуда.
Заменять удаление на установку флага именно на уровне хибера я бы тоже не стал. Так мы себе сразу отрубаем возможность делать полноценное удаление. Ведь оно тоже в будущем может понадобиться. Поэтому я бы менял удаление на установку флага уже на уровне бизнес-логики, а не доступа к данным. ИМХО, ты пытаешься перетянуть логику на уровень DAL. Этого не стоит делать.
Re: удаление без удаления в hibernate
От: dolor Китай  
Дата: 24.10.12 11:50
Оценка: 1 (1)
прикрутить envers?
Re[2]: удаление без удаления в hibernate
От: strcpy Россия  
Дата: 24.10.12 16:11
Оценка:
Здравствуйте, dolor, Вы писали:

D>прикрутить envers?

Вариант интересный. А можете с ходу сказать, оно будет дополнительную таблицу аудировать, которая появляется для отношения ManyToMany?
Спасибо.
Удвой число ошибок, если не получается добиться цели.
Re[3]: удаление без удаления в hibernate
От: dolor Китай  
Дата: 25.10.12 09:42
Оценка:
D>>прикрутить envers?
S>Вариант интересный. А можете с ходу сказать, оно будет дополнительную таблицу аудировать, которая появляется для отношения ManyToMany?
S>Спасибо.

конкретно manytomany не пробовал, но он ходит по зависимостям, если поле не помечено как @NotAudited
Re: удаление без удаления в hibernate
От: tavr  
Дата: 06.11.12 07:41
Оценка:
Здравствуйте, strcpy, Вы писали:

S>Это вроде работает. Но еще хочется добавить к каждой записи ссылку на журнал history, в котором бы была, скажем дата создания (она же дата удаления, если запись удаленная). Тут начинается проблема. Если я описываю внутри класса History ссылку на любой объект (я хочу чтобы history был у всех)


S>
S>    Object entity;
S>    @Column(name = "ENTITY")
S>    @OneToOne
S>    Object getEntity(){
S>        return entity;
S>    }
S>


S>то hibernate начинает ругаться, что мол нужен конкретный экземпляр, а не Object. Это в общем-то логично. Выделять общего предка у всех "неудаляемых" объектов мне не очень хочется, потому что в таком случае, насколько я понимаю, в SQL либо будет одна таблица с диким количеством столбцов, либо одна дополнительная общая таблица. Это не очень подходит, т.к. база данных будет дополнительно читаться с помощью SQL, и это все усложнит. Можно ли подключить history через поле object_id, внутри которого указана сущность в виде "X.12341", где x -- название сущности?


S>Может быть есть какие-то другие решения этой задачи? Более изящное решение?

вместо использования entity напрямую использовать класс
public class EntityLink {
    private Class entityClass;
    private Long entityId;
    ...
}

и замапитть его на одно поле через свой UserType
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.