Hibernate Envers和“Javassist Enhancement failed”异常

时间:2011-09-01 16:07:56

标签: hibernate hibernate-envers

我们正在使用Hibernate Envers并出现以下情况:

课程BusinessObjectType和课程Identity,引用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;

    […]

}

然后我们用以下方式查询所有版本的身份:

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

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

如果存储的身份没有BusinessObjectType(即businessObjectType并且为空),一切都像魅力一样。

如果身份有businessObjectType != null我们得到“Javassist Enhancement failed”异常:

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

错误似乎与Envers尝试实例化BusinessObjectType有关,但我真的没有看到问题是什么(如果我们不使用AuditQuery,Hibernate对这两个对象都没有问题。)

异常的原因是

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

没有堆栈跟踪。

有关问题可能是什么的暗示?

2 个答案:

答案 0 :(得分:20)

这发生在以下类JavassistLazyInitializer基于Javassist的惰性初始化代理中。

如果没有查看完整来源,很难发表评论,但您可以尝试以下选项。

  • 关闭@ManyToOne关系的延迟加载[这是一项设计决策,因此请注意它是否不适合整体解决方案]
  • 为您的实体提供一个默认的公共构造函数,这会导致问题[这更容易]
  • 如果不是真的需要将hibernate.bytecode.use_reflection_optimizer属性设置为false
  • ,则关闭反射优化

如果有帮助,请告诉我们

答案 1 :(得分:1)

要获取有关异常的更多信息,请使用IDE的调试工具为java.lang.InstantiationException设置异常断点,以便在发生基础异常时暂停执行。这应该显示完整的堆栈跟踪,并允许您检查堆栈上的所有变量。

如果我不得不猜测,我的第一个怀疑就是自从与...联系以来 BusinessObjectType没有映射到懒惰,普通的hibernate不会尝试为类创建代理。相反的情况似乎也是如此。代理是在运行时生成的子类,它覆盖所有公共方法。因此,类和任何公共方法(除了那些从Object继承的方法)都不能声明final,并且子类必须可以访问默认构造函数。