@Entity
public class User {
@ManyToMany(cascade = { MERGE, PERSIST, CascadeType.REFRESH }, fetch = LAZY)
@Cache(usage = READ_WRITE)
@UserRoles
private List<Role> roles = new ArrayList<Role>(0);
}
即使将它们声明为Lazy,它们也会被加载,即使它被声明为Lazy,它也可能被加载的原因
答案 0 :(得分:2)
根据JPA 2.0规范,延迟提取是对持久性提供程序的暗示。
第11.1.6节说:
EAGER战略是一项要求 持久性提供程序运行时 必须急切地获取数据。懒人 战略是对持久性的暗示 应该是数据的提供者运行时 它是第一次懒洋洋地取出来 访问。实施是 允许急切地获取数据 这是LAZY战略的暗示 指定。
在某些情况下,提供程序可能会确定懒惰地获取某些内容是没有意义的,或者提供程序可能甚至没有实现延迟提取。
PersistenceUtil.isLoaded方法可用于确定实体的加载状态 及其属性,与实体关联的持久性单元无关。
为确保您遇到此类问题,您应该使用此方法。当然,如果一个实体脱离了分支,那么对这个懒惰的领域的简单检查也会有所帮助。
除此之外,基于发布的代码为什么您的收藏品没有被懒惰地取出,我看不出特定的原因。我想也许你使用二级缓存的事实可能会影响到这种情况,但这是我尚未验证的,它只是一种预感。
<强> [EDIT-1] 强>
如果您使用的是最终类,则延迟加载也存在问题。 Hibernate文档在persistent classes:
下说Hibernate的核心功能, 代理,取决于持久性 上课要么是非最终的,要么是 实现一个接口 声明所有公共方法。
你可以坚持最后的课程 没有实现接口 休眠。但是,你不会 能够使用代理进行懒惰 关联取得哪个会 最终限制你的选择 性能调整。
你也应该避免宣布公开 关于非决赛的最终方法 类。如果你想使用一个类 用公共最终方法,你必须 通过设置显式禁用代理 懒惰= “假”。
<强> [EDIT-2] 强>
除此之外,2.1节中的JPA 2.0规范规定实体不得是最终的:
实体类不能是最终的。没有 方法或持久化实例 实体类的变量可以是 最终
稍后在2.5节中为嵌入式规定了同样的要求。
我无法访问JPA 1.0规范,但我相信这个要求也适用于它。试一试,看看是不是这个原因让我们知道。