我试图审核用户执行的导致相应表更改的操作。例如,如果用户要在两个帐户之间转账,这将生成以下事件序列:
将转账金额插入转账表
从科目1的余额表中减去转账金额。
将转账金额添加到帐户2的余额表中的余额。
所有表的父审核消息将是:“用户生成的金额XXX转账”
这是通过以下架构实现的:
schema
alt text http://img48.imageshack.us/img48/7460/auditloggingiv6.png
问题是我如何在hibernate中表示它?
我已经创建了以下内容:
平衡和传输的映射文件
<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" />
然后在使用aop和hibernate拦截器的日志类中,我有:
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\u id是使用方法上的注释设置的。
我在转移表上漏掉了“通过”一栏。以前,我调用save(transfer)将转账金额插入转账表,passed设置为false。(此操作也经过审计)。
我的需求比上面的例子稍微复杂一些:p
因此,上述事件的顺序应为:
更新传输表
插入AuditRecord(父级)
插入AuditRecord(子项)
插入TransferAuditRecord
插入平衡表
插入AuditRecord(子项)
插入平衡审计记录
插入平衡表
插入AuditRecord(子项)
插入平衡审计记录
但是,上面定义的级联选项在update语句中失败。hibernate拒绝将记录插入到多对多表中(即使auditrecord映射中未保存的值为“any”)。我总是想在多对多表中插入行,这样一次传输可能会有许多标记以前事件的审计记录。但是,最新事件决定了用户希望看到的消息。hibernate要么尝试更新多对多表和以前的auditrecord条目,要么干脆拒绝插入auditrecord和transferauditrecord,抛出transientobjectexception。
检索审核消息的方式如下:
msg=... + ((AuditRecord) balance.getAuditRecords().toArray()[getAuditRecords().size()-1])
.getParentAuditRecord().getAuditRecordType().getDescription() + ...;
信息应该这样说:
“2008年10月11日12:00将用户名设置为传递”
编辑我决定显式地映射多对多表(带有关联的接口),然后在aftertransactioncompletion中,调用父审计记录上的save(将save级联到子审计记录上),然后显式地将接口保存到所有子映射表上。这不是一个真实的审计历史,而是一种记录用户操作的非侵入性方法。如果我以后需要更完整的审计历史,我将调查envers。
最佳答案
似乎parentauditrecord和transferauditrecord以及balance auditrecord之间的关系不应该是一对多的。当我读到你输入的内容时,我看到它是一个表,按照审计层次结构的子类使用,这是一对一的关系。
http://www.hibernate.org/hib_docs/reference/en/html/inheritance.html
您可能还想查看jboss的envers项目。
关于java - 使用Hibernate和AOP进行审核架构映射,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/282023/