Hibernate Envers 和“Javassist 增强失败”例外
我们使用 Hibernate Envers 并遇到以下情况:
一个 BusinessObjectType
类和一个引用 BusinessObjectType
的类 Identity
:
@Entity
@Table( name = "ID_IDENTITY" )
@Audited
public class Identity {
@ManyToOne
@JoinColumn( name = "BO_TYPE_ID" )
@IndexColumn( name = "INDEX_BO_BO_TYPE" )
private BusinessObjectType businessObjectType;
[…]
}
然后我们查询所有Identity 的版本:
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
是并且曾经是 null),那么一切都会像魅力一样工作。
如果身份具有 businessObjectType != null
我们会收到“Javassist 增强失败”异常:
Javassist Enhancement failed: ch.ethz.id.wai.baseclasses.BusinessObjectType
该错误似乎与 Envers 尝试实例化 BusinessObjectType 有关,但我真的不明白问题出在哪里(如果我们不使用 AuditQuery,Hibernate 对这两个对象都没有问题)。
异常的原因是
java.lang.InstantiationException: ch.ethz.id.wai.baseclasses.BusinessObjectType_$$_javassist_49
没有堆栈跟踪。
关于问题可能是什么的任何提示吗?
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?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
这发生在以下类 JavassistLazyInitializer 基于 Javassist 的惰性初始化器 代理人。
如果不查看完整源代码,很难发表评论,但您可以尝试以下选项。
让我们知道这是否有帮助
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.
hibernate.bytecode.use_reflection_optimizer
property to falseLet us know if this helps
要获取有关异常的更多信息,请使用 IDE 的调试工具为 java.lang.InstantiationException 设置异常断点,以便在发生基础异常时停止执行。这应该显示完整的堆栈跟踪,并允许您检查堆栈上的所有变量。
如果我必须猜测的话,我的第一个怀疑是,自从与
BusinessObjectType 未映射为惰性,普通 Hibernate 不会尝试为该类创建代理。相比之下,恩弗斯似乎确实如此。代理是在运行时生成的子类,覆盖所有公共方法。因此,类和任何公共方法(除了从
Object
继承的方法)都不能被声明为final
,并且子类必须可以访问默认构造函数。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 fromObject
) may be declaredfinal
, and a default constructor must be accessible to the subclass.