如何确定Hibernate是“懒加载”代理还是真实对象?

5

我是一名新手,正在学习Hibernate。我使用的是Hibernate 3.5版本,它默认应该使用延迟加载。我已经通过SQL日志启用了SQL查询记录。

<property name="show_sql">true</property>

我请求对象A,它引用了持有实际数据字节数组的对象B。我将数据推送到对象B中,以便不必在真正需要时从数据库获取数据,但是当我请求对象A时,堆跳跃急剧增加,就好像已经获取了数据一样,并且我从Hibernate SQL日志中得到以下输出:

Hibernate: select attachment0_.id as id11_0_, attachment0_.data as data11_0_ from attachment_data attachment0_ where attachment0_.id=?

我对如何解释这个问题不清楚,特别是'as'语句。'attachment0.data'似乎是对象B中的字节数组。Hibernate是在说它为数组创建了代理,还是说它实际上从数据库中提取了数据?如果它只是创建了一个代理,那么我会看不到代理的任何选择输出吗?

因此,总结一下,主要问题是如何确定我是否有代理或真实对象,以及如何解释选择语句?

我已经深入研究了Hibernate文档,并在网上搜索了很多,但大部分信息似乎都超出了我缺少的基本知识范围,所以任何帮助都将不胜感激。


attachment_data是映射到对象A还是对象B的表格? - Tahir Akhtar
1个回答

3
你所拥有的对象可以是一个代理,其中包含所有加载的数据。如果你想取消代理对象,请使用以下方法在Hibernate中实现:
从一个org.hibernate.impl.SessionImpl中获取org.hibernate.engine.PersistenceContext,然后进行操作。
SessionImpl session = ...;
PersistenceContext persistenceContext = session.getPersistenceContext();
Object entity = persistenceContext.unproxy(maybeProxy);

unproxy的Javadoc

/**
 * Get the entity instance underlying the given proxy, throwing
 * an exception if the proxy is uninitialized. If the given object
 * is not a proxy, simply return the argument.
 */
public Object unproxy(Object maybeProxy) throws HibernateException;

谢谢回复。你说对象可以是代理,其中包含所有已加载的数据,但这有什么意义呢?对象实际上只是一个容器,包含数据和方法,那么在Hibernate传递代理与真实对象的上下文中,代理和真实对象有什么区别呢? - spiffly
让我澄清一下我的意思:首先,您会得到一个代理实例,该实例是按需初始化的,可以通过Session.load(假设数据不在一级缓存中)或浏览关系来完成。然后当访问代理的属性时,实体数据将从数据库中获取。Java对象实例仍然是代理(虽然所有数据都已加载),并且在您将其“取消代理”之前,它将继续保持为代理。对于Hibernate,您可以随意使用代理或真实对象。 - Nr9
有趣,谢谢。只要数据和方法相同,我想处理代理对象或真实对象并没有太大区别。 - spiffly
@Nr9:我想了解PersistenceContext对象的unproxy方法是深度还是浅层的?谢谢。 - Thinhbk

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接