Reputation: 2203
I'm having issues when trying to get audited entities referencing to entities that are not audited. In our application, certain entities are bootstrapped without the use of hibernate, those entities are our meta-model and do not need to be audited.
public class A {
private String id;
private List<B> attributeReferences;
}
public class B {
private String id;
private A attributeReference;
}
If I execute the code:
A rev1 = getAuditReader().find(A.class, "foo", 1);
A rev2 = getAuditReader().find(A.class, "foo", 2);
A rev3 = getAuditReader().find(A.class, "foo", 3);
Everything goes well, however if I try to get a version of B the error occurs:
B rev2 = getAuditReader().find(B.class, "bar", 2);
org.hibernate.ObjectNotFoundException: No row with the given identifier exists [metafoo]
Envers successfully does the lookup of the B entity with a lazy reference to my metafoo entity. However when trying to store that in its cache the hashcode method of my B entity gets called, which in turn does a lookup for metafoo which does not exist in the audit tables, raising the exception.
Is there a way I could ignore those inexistent references instead of throwing this error? (maybe by excluding such references in the query)
How to deal with inexistent data altogether (suppose we deleted all entries older than 1 month from the audit table) how could we still query entities referencing to inexistent ones?
I'd like not to modify the hashcode function if possible
I'd like not to audit my meta model
table A:
ID
----------------------------------------
metaFooAttribute
fooAttribute
foo
table A_AUD:
REV REVTYPE ID
----------------------------------------
1 0 fooAttribute
1 0 foo
2 1 foo
3 1 foo
table B:
ID
----------------------------------------
bar
table B_AUD:
REV REVTYPE ID ATTRIBUTE_ID
----------------------------------------
1 0 bar metaFooAttribute
1 0 bar fooAttribute
2 1 bar fooAttribute
org.hibernate.ObjectNotFoundException: No row with the given identifier exists: [playground.test.A#metafoo]
at org.hibernate.impl.SessionFactoryImpl$2.handleEntityNotFound(SessionFactoryImpl.java:435)
at org.hibernate.proxy.AbstractLazyInitializer.checkTargetState(AbstractLazyInitializer.java:189)
at org.hibernate.proxy.AbstractLazyInitializer.initialize(AbstractLazyInitializer.java:178)
at org.hibernate.proxy.AbstractLazyInitializer.getImplementation(AbstractLazyInitializer.java:215)
at org.hibernate.proxy.pojo.cglib.CGLIBLazyInitializer.invoke(CGLIBLazyInitializer.java:189)
at playground.test.A$$EnhancerByCGLIB$$3cdb0441.hashCode(<generated>)
at playground.test.B.hashCode(B.java:120)
at org.hibernate.envers.tools.Triple.hashCode(Triple.java:73)
at java.util.HashMap.put(HashMap.java:372)
at org.hibernate.envers.reader.FirstLevelCache.putOnEntityNameCache(FirstLevelCache.java:94)
at org.hibernate.envers.entities.EntityInstantiator.createInstanceFromVersionsEntity(EntityInstantiator.java:105)
at org.hibernate.envers.entities.EntityInstantiator.addInstancesFromVersionsEntities(EntityInstantiator.java:113)
at org.hibernate.envers.query.impl.EntitiesAtRevisionQuery.list(EntitiesAtRevisionQuery.java:110)
at org.hibernate.envers.query.impl.AbstractAuditQuery.getSingleResult(AbstractAuditQuery.java:108)
at org.hibernate.envers.reader.AuditReaderImpl.find(AuditReaderImpl.java:119)
at org.hibernate.envers.reader.AuditReaderImpl.find(AuditReaderImpl.java:94)
at playground.test.TestEnvers.testGetAttribute(TestActivityStream.java:60)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:45)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:42)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:20)
at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:28)
at org.springframework.test.context.junit4.statements.RunBeforeTestMethodCallbacks.evaluate(RunBeforeTestMethodCallbacks.java:74)
at org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks.evaluate(RunAfterTestMethodCallbacks.java:82)
at org.springframework.test.context.junit4.statements.SpringRepeat.evaluate(SpringRepeat.java:72)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:240)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:47)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:231)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:60)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:229)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:50)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:222)
at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:28)
at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)
at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:70)
at org.junit.runners.ParentRunner.run(ParentRunner.java:300)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:180)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)
I found this post interesting but it does not solve the problem as my reference is of type A so the annotation @Audited(targetAuditMode = RelationTargetAuditMode.NOT_AUDITED) does not work.
Upvotes: 3
Views: 4032
Reputation: 8636
Maybe try adding @NotAudited to the meta-field. Then the field won't be audited, but it looks as if you don't want to audit it. Otherwise @Audited(targetAuditMode = RelationTargetAuditMode.NOT_AUDITED) is the way to go.
Upvotes: 1