我正在將envers添加到現有的hibernate實體中。到目前爲止,審計工作一切正常,但查詢是一個不同的問題,因爲修訂表沒有填充現有數據。其他人是否已經解決了這個問題?也許你已經找到了一些方法來用現有的表格填充修訂表格?只是想我會問,我相信別人會覺得它有用。使用現有數據從Hibernate實體填充envers修訂表
19
A
回答
5
你不需要。
AuditQuery允許你通過得到兩個RevisionEntity和數據修訂:
AuditQuery query = getAuditReader().createQuery()
.forRevisionsOfEntity(YourAuditedEntity.class, false, false);
這將構建一個查詢返回的對象[3]的列表。 Fisrt元素是您的數據,第二個是修訂實體,第三個是修訂類型。
1
看看http://www.jboss.org/files/envers/docs/index.html#revisionlog
基本上你可以使用@RevisionEntity註釋, 定義自己的修訂類型「,然後實施RevisionListener接口插入你額外的審計數據, 像當前用戶和高級操作。通常這些是從ThreadLocal上下文中提取的。
12
我們通過運行一系列原始SQL查詢來填充初始數據,以模擬「插入」所有現有實體,就好像它們剛剛在同一時間創建一樣。例如:
insert into REVINFO(REV,REVTSTMP) values (1,1322687394907);
-- this is the initial revision, with an arbitrary timestamp
insert into item_AUD(REV,REVTYPE,id,col1,col1) select 1,0,id,col1,col2 from item;
-- this copies the relevant row data from the entity table to the audit table
注意,REVTYPE值爲以指示刀片(相對於變形例)。
2
我們已經解決了與現有數據填充審計日誌的問題如下:
SessionFactory defaultSessionFactory;
// special configured sessionfactory with envers audit listener + an interceptor
// which flags all properties as dirty, even if they are not.
SessionFactory replicationSessionFactory;
// Entities must be retrieved with a different session factory, otherwise the
// auditing tables are not updated. (this might be because I did something
// wrong, I don't know, but I know it works if you do it as described above. Feel
// free to improve)
FooDao fooDao = new FooDao();
fooDao.setSessionFactory(defaultSessionFactory);
List<Foo> all = fooDao.findAll();
// cleanup and close connection for fooDao here.
..
// Obtain a session from the replicationSessionFactory here eg.
Session session = replicationSessionFactory.getCurrentSession();
// replicate all data, overwrite data if en entry for that id already exists
// the trick is to let both session factories point to the SAME database.
// By updating the data in the existing db, the audit listener gets triggered,
// and inserts your "initial" data in the audit tables.
for(Foo foo: all) {
session.replicate(foo, ReplicationMode.OVERWRITE);
}
(通過Spring)的我的數據源配置:
<bean id="replicationDataSource"
class="org.apache.commons.dbcp.BasicDataSource"
destroy-method="close">
<property name="driverClassName" value="org.postgresql.Driver"/>
<property name="url" value=".."/>
<property name="username" value=".."/>
<property name="password" value=".."/>
<aop:scoped-proxy proxy-target-class="true"/>
</bean>
<bean id="auditEventListener"
class="org.hibernate.envers.event.AuditEventListener"/>
<bean id="replicationSessionFactory"
class="o.s.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
<property name="entityInterceptor">
<bean class="com.foo.DirtyCheckByPassInterceptor"/>
</property>
<property name="dataSource" ref="replicationDataSource"/>
<property name="packagesToScan">
<list>
<value>com.foo.**</value>
</list>
</property>
<property name="hibernateProperties">
<props>
..
<prop key="org.hibernate.envers.audit_table_prefix">AUDIT_</prop>
<prop key="org.hibernate.envers.audit_table_suffix"></prop>
</props>
</property>
<property name="eventListeners">
<map>
<entry key="post-insert" value-ref="auditEventListener"/>
<entry key="post-update" value-ref="auditEventListener"/>
<entry key="post-delete" value-ref="auditEventListener"/>
<entry key="pre-collection-update" value-ref="auditEventListener"/>
<entry key="pre-collection-remove" value-ref="auditEventListener"/>
<entry key="post-collection-recreate" value-ref="auditEventListener"/>
</map>
</property>
</bean>
攔截:
import org.hibernate.EmptyInterceptor;
import org.hibernate.type.Type;
..
public class DirtyCheckByPassInterceptor extends EmptyInterceptor {
public DirtyCheckByPassInterceptor() {
super();
}
/**
* Flags ALL properties as dirty, even if nothing has changed.
*/
@Override
public int[] findDirty(Object entity,
Serializable id,
Object[] currentState,
Object[] previousState,
String[] propertyNames,
Type[] types) {
int[] result = new int[ propertyNames.length ];
for (int i = 0; i < propertyNames.length; i++) {
result[ i ] = i;
}
return result;
}
}
ps:請記住,這是一個簡化的例子。它不會開箱即用,但它會引導您找到一個可行的解決方案。
5
如果您正在使用Envers ValidityAuditStrategy並且創建的數據不是啓用了Envers,那麼您將會遇到此類別的問題。 (Hibernate 4.2.8.Final)基本對象更新拋出「無法更新實體和以前的修訂」(記錄爲[org.hibernate.AssertionFailure] HHH000099)。
我花了一段時間來找到這個討論/解釋這樣交叉發佈:
相關問題
- 1. 如何使用spring數據envers查找實體的所有修訂版本?
- 2. envers多級實體修訂howto
- 3. Hibernate Envers:使用集合屬性檢索實體的正確修訂
- 4. 使用NHibernate填充現有實體
- 5. Hibernate Envers獲取修訂條件
- 6. 在Hibernate Envers中放棄修訂版
- 7. 使用json數據填充實現自動填充
- 8. 使用spock數據表填充物體
- 9. Hibernate Envers如何根據EmbeddedId的屬性得到修訂
- 10. 將Envers修訂添加到現有和未審計的表
- 11. 如何使用hibernate envers獲取Audited表中的所有數據?
- 12. EclipseLink的Hibernate Envers(實體審計)
- 13. 獲取完整的實體,與Hibernate envers
- 14. 使用NodeJS在現有PDF窗體中填充數據
- 15. 數據表不填充在struts2中hibernate
- 16. Nhibernate envers,使用依賴注入將用戶添加到修訂實體
- 17. 用數據填充現有表使用JQuery
- 18. 創建Envers自定義修改實體
- 19. 填充從數據表
- 20. 使用現有數據填充流星React表單
- 21. 在休眠Envers是否可以查詢給定修訂的所有實體?
- 22. Hibernate Envers來自修訂日期的時間戳
- 23. 使用Access數據庫表填充現有的SQL Server數據庫表
- 24. Hibernate - Envers:是否可以使用SQL觸發器來創建修訂
- 25. 用相關實體填充列表框
- 26. 是否有數據庫實現有通知和修訂?
- 27. 如何不使用Hibernate Envers審計連接表和相關實體?
- 28. 使用Hibernate實體標準的現有表連接
- 29. 使用上下文實體框架填充數據集4
- 30. 如何使用實體框架填充數據庫
你是如何獲取的審計工作?我什至不能得到那麼遠:( – 2009-06-04 16:07:25
這真的很簡單,只是閱讀相當簡短的手冊:http://www.jboss.org/files/envers/docs/index.html – danieljimenez 2009-06-05 05:29:50
我想知道這件事,但我需要有關環境的審計信息。哪個用戶和他們「做了些什麼」改變 - 他們正在做哪些高級用戶操作,從而觸發了這種變化。這對於能夠看到明顯的變化與「副作用」變化很重要。你知道恩維爾是否處理這種需求? – Pat 2009-06-15 22:48:41