gpt4 book ai didi

hibernate - 最后一个方法是否会阻止 Hibernate 为这样的实体创建代理?

转载 作者:行者123 更新时间:2023-12-03 13:56:39 26 4
gpt4 key购买 nike

Hibernate 使用代理来启用延迟加载集合甚至单端关联。根据 Hibernate 的 (3.6.5) 引用文档(第 21.1.3 节,单端关联代理),如果包含“任何 final方法”,则 Hibernate 不能构造这样的代理。
我的问题是,这个限制是仅适用于持久字段的 getter/setter 还是真的适用于实体类中的任何方法?那么,是否有这样的方法:

public final String toString() {
return this.getClass().getSimpleName() + id;
}

真的阻止为该实体创建(CGLIB 或 Javassist)代理吗?
使用基于字段或属性访问是否重要?既然 CGLIB 被 Javassist 取代了,这是否在这个方向上提供了更多的特性?

我喜欢在我的实体层次结构中使用继承,因此需要定义一些 final方法,
例如,在基类中防止子类覆盖这些方法。

提前致谢!

最佳答案

在 Hibernate 邮件列表的帮助下(感谢 Emmanuel Bernardt!)我能够回答我自己的问题,摘要是:
通常, final方法不会阻止 Hibernate 创建代理,但除非这些方法不使用实体的任何状态,否则这是非常不可取的。

一些背景信息: Hibernate 既不使用 cglib 也不使用 Javassist 的字节码增强,因此,为了让代理延迟初始化其目标实体,它必须拦截任何可能使用该目标实体状态的方法。
现在有一个像这样的 final方法是完全可以的

public final doSomething(String a, Integer b ) {
// do complicated stuff using only a and b (no instance members accessed!)
}

但是一旦此方法直接或通过另一个实例方法使用任何持久字段,这将绕过代理,从而导致意外行为。

作为旁注,这与您不应该直接访问其他实例的字段的原因相同,例如在实体 equals 中。方法:
// XXX bad code!
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof Profile)) return false;
Profile profile = (Profile) o;
// XXX this bypasses a possible proxy, use profile.getName() instead!
return (name == null ? profile.name == null : name.equals(profile.name));
}

关于hibernate - 最后一个方法是否会阻止 Hibernate 为这样的实体创建代理?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6608222/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com