Question

We are using Hibernate Envers and have the following situation:

A class BusinessObjectType and a class Identity with a reference to BusinessObjectType:

@Entity
@Table( name = "ID_IDENTITY" )
@Audited
public class Identity {

    @ManyToOne
    @JoinColumn( name = "BO_TYPE_ID" )
    @IndexColumn( name = "INDEX_BO_BO_TYPE" )
    private BusinessObjectType businessObjectType;

    […]

}

We then query for all the version of Identity with:

AuditQuery auditQuery = auditReader.createQuery().forRevisionsOfEntity(
    Identity.class,
    false,
    true );
auditQuery.add( AuditEntity.id().eq( dbid ) );

@SuppressWarnings( "unchecked" )
List< Object[]> history = (List< Object[]>) auditQuery.getResultList();

If the stored identity does not have a BusinessObjectType (i.e., businessObjectType is and was null) everything works like a charm.

If the identity had a businessObjectType != null we get a "Javassist Enhancement failed" Exception:

Javassist Enhancement failed: ch.ethz.id.wai.baseclasses.BusinessObjectType

The error seems to be related to Envers trying to instantiate a BusinessObjectType but I don't really see what the problem could be (Hibernate has no problems with both objects if we don't use an AuditQuery).

The cause of the exception is

java.lang.InstantiationException: ch.ethz.id.wai.baseclasses.BusinessObjectType_$$_javassist_49

with no stack trace.

Any hint on what the problem could be?

Était-ce utile?

La solution

This happens inside the following class JavassistLazyInitializer A Javassist-based lazy initializer proxy.

Without having a look at full source it is difficult to comment but you can try following options.

  • Turn off Lazy loading for @ManyToOne relationship [This is a design decision so watch out if it doesn't fit in overall solution]
  • Provide a default public constructor for your entity which is causing problem[This is easier]
  • turn off reflection optimisation if not really required by setting up hibernate.bytecode.use_reflection_optimizer property to false

Let us know if this helps

Autres conseils

To get a more information about the exception, use the debugging facilities of your IDE to set an exception breakpoint for java.lang.InstantiationException to halt execution when the underlying exception occurs. This should show you the full stack trace, and allow you to inspect all variables on the stack.

If I had to guess, my first suspicion would be that since the association to BusinessObjectType is not mapped lazy, plain hibernate doesn't ever try to create a proxy for the class. Envers in contrast appears to do. A proxy is a subclass generated at runtime overriding all public methods. Therefore, neither the class nor any public methods (beside those inherited from Object) may be declared final, and a default constructor must be accessible to the subclass.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top