Нужно сделать так, чтобы удаленные записи не выкашивались из базы данных, чтобы потом можно было без возни с бэкапом посмотреть что случилось. Можно вот такую схему провернуть:
@Entity
@Where(clause = "deleted <> 1")
@Table(name = "X")
@SQLDelete(sql = "UPDATE X SET deleted = '1' WHERE id = ?")
public class X {
// внутри описание столбца deleted
}
Это вроде работает. Но еще хочется добавить к каждой записи ссылку на журнал history, в котором бы была, скажем дата создания (она же дата удаления, если запись удаленная). Тут начинается проблема. Если я описываю внутри класса History ссылку на любой объект (я хочу чтобы history был у всех)
то hibernate начинает ругаться, что мол нужен конкретный экземпляр, а не Object. Это в общем-то логично. Выделять общего предка у всех "неудаляемых" объектов мне не очень хочется, потому что в таком случае, насколько я понимаю, в SQL либо будет одна таблица с диким количеством столбцов, либо одна дополнительная общая таблица. Это не очень подходит, т.к. база данных будет дополнительно читаться с помощью SQL, и это все усложнит. Можно ли подключить history через поле object_id, внутри которого указана сущность в виде "X.12341", где x -- название сущности?
Может быть есть какие-то другие решения этой задачи? Более изящное решение?
Удвой число ошибок, если не получается добиться цели.
Здравствуйте, strcpy, Вы писали:
S>то hibernate начинает ругаться, что мол нужен конкретный экземпляр, а не Object. Это в общем-то логично. Выделять общего предка у всех "неудаляемых" объектов мне не очень хочется
Сделайте общего предка у History, и конкретные экземпляры — Entity1History, Entity2History и т.д. Это можно представить в БД в виде 1 таблицы со множеством полей.
Еще можно сделать один History, но завести поле type, куда писать тип объекта. Ну и в поле key — первичный ключ. Но тогда ссылки на объекты придется расставлять самому.
Здравствуйте, strcpy,
S>Нужно сделать так, чтобы удаленные записи не выкашивались из базы данных, чтобы потом можно было без возни с бэкапом посмотреть что случилось. Можно вот такую схему провернуть:
Подход к решению немного странный. Если ты решил таки оставлять записи, то, вероятно, для того чтобы позже где-то читать. Решение с флагом не очень хорошее по той причине что это флаг придется тянуть по всему проекту. Как, например, на счет отчетов?
Ты как бы пишешь "всегда читать только deleted=false", но при этом иногда когда очень надо читать и "deleted=true".
Мне кажется интересной была бы идея вынести часть реализации на базу. Удаленные записи переносить в отдельный сегмент по триггеру, например. Либо сделать View для только акутальных записей и читать оттуда.
Заменять удаление на установку флага именно на уровне хибера я бы тоже не стал. Так мы себе сразу отрубаем возможность делать полноценное удаление. Ведь оно тоже в будущем может понадобиться. Поэтому я бы менял удаление на установку флага уже на уровне бизнес-логики, а не доступа к данным. ИМХО, ты пытаешься перетянуть логику на уровень DAL. Этого не стоит делать.
Здравствуйте, dolor, Вы писали:
D>прикрутить envers?
Вариант интересный. А можете с ходу сказать, оно будет дополнительную таблицу аудировать, которая появляется для отношения ManyToMany?
Спасибо.
Удвой число ошибок, если не получается добиться цели.
D>>прикрутить envers? S>Вариант интересный. А можете с ходу сказать, оно будет дополнительную таблицу аудировать, которая появляется для отношения ManyToMany? S>Спасибо.
конкретно manytomany не пробовал, но он ходит по зависимостям, если поле не помечено как @NotAudited
Здравствуйте, strcpy, Вы писали:
S>Это вроде работает. Но еще хочется добавить к каждой записи ссылку на журнал history, в котором бы была, скажем дата создания (она же дата удаления, если запись удаленная). Тут начинается проблема. Если я описываю внутри класса History ссылку на любой объект (я хочу чтобы history был у всех)
S>
S>то hibernate начинает ругаться, что мол нужен конкретный экземпляр, а не Object. Это в общем-то логично. Выделять общего предка у всех "неудаляемых" объектов мне не очень хочется, потому что в таком случае, насколько я понимаю, в SQL либо будет одна таблица с диким количеством столбцов, либо одна дополнительная общая таблица. Это не очень подходит, т.к. база данных будет дополнительно читаться с помощью SQL, и это все усложнит. Можно ли подключить history через поле object_id, внутри которого указана сущность в виде "X.12341", где x -- название сущности?
S>Может быть есть какие-то другие решения этой задачи? Более изящное решение?
вместо использования entity напрямую использовать класс
public class EntityLink {
private Class entityClass;
private Long entityId;
...
}