如何加载实际的 Hibernate 实体关联而不是 LAZY 代理

How to load the actual Hibernate entity association and not the LAZY proxy

我来自 eclipselink 并尝试通过 Hibernate 工作。

假设我们有一个 class Car 和一个 class WheelCar class 有n个轮子。两个实体都通过双向关联进行连接。更重要的是,在 Wheel 方面,我有一个 Car 参考:

@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "car_id")
private Car car;

加一个getter.

现在我想使用它的 id 获取一个轮子。来自我的 EntityManager(不是休眠 Session)。我这样初始化 EntityManager

EntityManagerFactory emf = Persistence.createEntityManagerFactory(PERSISTENCE_UNIT_NAME);
EntityManager em = emf.createEntityManager();

下一步是像这样取一个轮子:

Wheel wheel = em.find(Wheel.class, 1);

车轮 return 想要的 class 很好。现在我想知道哪辆车是车轮的父级:

Car car = wheel.getCar();

有了eclipselink,真车就装好了。使用休眠代理 class 代替加载。

到目前为止,我唯一的解决方案是设置 FetchType.EAGER 或直接获取加入关系。我意识到 Hibernate 中的 SQL 语句仍在执行,但没有传递真正的对象。同样在

之后
Hibernate.initalize(car)

我无法检索到汽车实体。

有没有什么方法可以在不形成查询或急切获取的情况下取回预期的对象?

您需要使用特定于 Hibernate 的 LazyToOneOption.NO_PROXY 注释:

@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "car_id")
@LazyToOne(LazyToOneOption.NO_PROXY)
private Car car;

这将指示 Hibernate 加载实际对象,而不是给你一个代理:

Lazy, give back the real object loaded when a reference is requested (Bytecode enhancement is mandatory for this option, fall back to PROXY if the class is not enhanced) This option should be avoided unless you can't afford the use of proxies

但是您必须使用字节码检测来激活此选项。

您可能不需要担心代理。代理应该 return 所有属性都与普通对象相同。

如果代理对象不工作(它是 returning 空值),可能是您的某些字段或 setter 或 getter 设置为 final。先检查一下。