我正在使用Hibernate Envers来保存对象历史记录.在某些时候,我们想要捕获对象图状态的快照 - 我们可以通过了解相应的Envers修订来实现这一点,然后我们将其存储在审计记录中.
但是我们有一个问题.父对象在我们创建和存储其子审计记录的同一事务中更新 - 完成Envers修订.我们可以得到最新版本:
Number revision = reader.getRevisionNumberForDate(new Date(Long.MAX_VALUE));
Run Code Online (Sandbox Code Playgroud)
或创建新版本:
Number revision = reader.getCurrentRevision(DefaultRevisionEntity.class, true).getId();
Run Code Online (Sandbox Code Playgroud)
并使用其中任何一个,但父母的提交总是发生在那之后.这就是Envers增加修订版的时候.因此,我们实际需要在审计记录中引用的修订始终高于存储的值.在最简单的情况下,我们获取并存储修订版N,但我们需要的父版本存储为N + 1.
可以使用以下方式获取AuditReader读者参考:
JpaTransactionManager transactionManager; // injected
EntityManagerFactory emf = transactionManager.getEntityManagerFactory();
EntityManager entityManager = emf.createEntityManager();
AuditReader reader = AuditReaderFactory.get(entityManager);
Run Code Online (Sandbox Code Playgroud)
我们正在使用Spring 3 @Transactional注释和Hibernate 4.2.
最小的类图:
Parent.class
int version // for hibernate optimistic locking
String revisionName
List<AuditChild> audits
AuditChild.class
int enversRevision // use to retrieve previous graphs of parent
Run Code Online (Sandbox Code Playgroud)
我尝试了许多方法来强制父项的提交首先发生,其中包括:
我尝试的一切都没有效果或引起其他问题.我很高兴听到有效的解决方案.谢谢.
使用 dom4j DOMDocument 来提供 validator.validate(DOMSource) 在 java 1.6 中失败(xsi:noNamespaceSchemaLocation 不允许出现在根元素中),在 1.5 中有效
我发现以下问题非常棘手(好吧,这是轻描淡写) - 任何见解将不胜感激。目前似乎最好的主意是放弃 dom4j 以支持 XOM(http://stackoverflow.com/questions/831865/what-java-xml-library-do-you-recommend-to-replace-dom4j)。
我一直在验证从 dom4j 'new DOMDocument()' 创建的内存 XML - 但这不适用于 Java 6。
以下对 dom4j (1.6.1) DOMDocument 派生的 DOMSource 的 validate(source) 调用适用于 Java 1.5.x,但在 Java 1.6.x 中失败:
public void validate() throws Exception {
SchemaFactory schemaFactory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
schemaFactory.setErrorHandler(null);
Schema schemaXSD = schemaFactory.newSchema(new URL(getSchemaURLString()));
Validator validator = schemaXSD.newValidator();
DOMSource source = new DOMSource(getDocument());
validator.validate(source);
}
Run Code Online (Sandbox Code Playgroud)
getSchemaURLString() 也用于在根节点添加 xsi:noNamespaceSchemaLocation 属性,即: xsi:noNamespaceSchemaLocation="http://localhost:8080/integration/xsd/fqlResponseSchema-2.0.xsd"
异常如下:
Exception: org.xml.sax.SAXParseException: cvc-complex-type.3.2.2: Attribute 'xsi:noNamespaceSchemaLocation' …Run Code Online (Sandbox Code Playgroud)