Я пытаюсь проверить действие, которое пользователь выполнил, что привело к изменениям в соответствующих таблицах. Например, если пользователь был переводить деньги между счетами 2 это создаст следующую последовательность событий:Отображение схемы схемы с помощью Hibernate и AOP
- Вставить сумму перевода в таблицу передачи
- сумму перевода Вычесть из баланса в баланс Таблица для счета 1.
- Добавить сумму перевода баланса в таблице баланса для счета 2.
сообщение родительского аудита для всех таблиц будет: «Пользователь генерироваться перевод на сумму XXX»
Это достигается с помощью следующей схемы: schema
alt text http://img48.imageshack.us/img48/7460/auditloggingiv6.png
Вопрос в том, как я могу представить это в спящий режим?
Я создал следующее:
В Равновесие и файлы сопоставления переводополучателя
<set name="auditRecords" table="TransferAuditRecord" inverse="false" cascade="save-update">
<key>
<column name="AuditRecordID" not-null="true" />
</key>
<one-to-many class="audit.AuditRecord"/>
</set>
Передача и баланс классов затем реализовать IAuditable, который имеет методы
public void setAuditRecords(Set<AuditRecord> auditRecord);
public Set<AuditRecord> getAuditRecords();
В файле отображения AuditRecord, я есть :
<many-to-one name="parentAuditRecord" lazy="false"
column="parent_id"
class="audit.AuditRecord"
cascade="all" />
Тогда в классе Logging с помощью АОП и гибернации Перехватчики у меня есть:
AuditRecord auditRecord = new AuditRecord();
auditRecord.setUser(userDAO.findById(
org.springframework.security.context.SecurityContextHolder.getContext()
.getAuthentication().getName()));
auditRecord.setParentAuditRecord(getCurrentActiveServiceRecord());
auditable.getAuditRecords().add(auditRecord);
Тогда в классе обслуживания я называю следующий метод, заключенный в сделке:
save(balance1);
save(balance2);
transfer.setPassed(true);
update(transfer);
parentAuditRecord создается с помощью AOP с потоковым безопасным стеком, а AuditRecordType_id задается с помощью аннотаций метода.
Я оставил «пройденный» столбец на переносном столе. Раньше я вызываю save (transfer), чтобы вставить сумму перевода в таблицу Transfer с переданным значением false. (Это действие также проверяется).
Мои требования немного более сложным, чем вышеприведенный пример: P
Так последовательность событий для выше должно быть:
- Update Transfer Таблица
- Вставьте в AuditRecord (Parent)
- Вставить в AuditRecord (Ребенок)
- Вставить в TransferAuditRecord
- Вставки в балансе Таблицу
- Вставить в AuditRecord (ребенок)
- Вставить в BalanceAuditRecord
- Вставить в Balance таблицу
- Вставить в AuditRecord (ребенок)
- Вставить в BalanceAuditRecord
Однако параметры каскада, определенные выше, выходят из строя в операторе обновления. Hibernate отказывается вставлять запись в таблицу «многие ко многим» (даже если unsaved-value = «any» в Mapping AuditRecord). Я всегда хочу вставлять строки в таблицы «многие-ко-многим», поэтому потенциально одна Transfer имеет много записей аудита, обозначающих предыдущие события. Однако последнее событие определяет сообщение, которое пользователь хочет видеть. Hibernate либо пытается обновить таблицу «многие ко многим», либо предыдущие записи AuditRecord, либо просто отказывается вставлять в AuditRecord и TransferAuditRecord, бросая исключение TransientObjectException.
Аудиторский сообщение извлекается что-то вроде этого:
msg=... + ((AuditRecord) balance.getAuditRecords().toArray()[getAuditRecords().size()-1])
.getParentAuditRecord().getAuditRecordType().getDescription() + ...;
Сообщение должно сказать что-то вроде этого: "Имя пользователя установить передачу переданному в 12:00 11-окт-2008"
EDIT Я решил пойти с явным отображением таблицы «много-ко-многим» (с соответствующим интерфейсом), а затем в afterTransactionCompletion, вызвав сохранение записи родительского аудита (которая каскадирует сохранение в дочерние записи аудита), а затем явно сохраняет интерфейс по всем дочерним картам столы. Это не настоящая история аудита, а не неинвазивный метод записи действий пользователя. Я рассмотрю Envers, если мне понадобится более полная история аудита на более позднем этапе.