Hibernate Envers 和“Javassist 增强失败”例外

发布于 2024-12-02 09:33:49 字数 1322 浏览 1 评论 0原文

我们使用 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

夜空下最亮的亮点 2024-12-09 09:33:49

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

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

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

让我们知道这是否有帮助

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

猛虎独行 2024-12-09 09:33:49

要获取有关异常的更多信息,请使用 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 from Object) may be declared final, and a default constructor must be accessible to the subclass.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文