为什么hibernate会返回代理对象?

6 java spring hibernate

我有一个调用DAO的服务方法,然后DAO从数据库返回一个对象.从系统的许多部分调用此方法.但是,一种特殊方法是获取返回类型的ObjectClass _ $$ _ javassist_somenumber作为类型.哪个是扔东西.我调用的服务方法与其他地方完全相同,那么为什么hibernate会返回代理而不是自然对象呢?

我知道有办法揭露"代理"对象,但我不觉得我应该这样做.

查询很简单

hibernateTemplate.find("from User u where u.username = ?", username)
Run Code Online (Sandbox Code Playgroud)

我正在使用hibernate 3.3 btw.

rhu*_*rhu 9

它是一个代理对象,以支持延迟加载; 基本上只要通过访问器/ getter方法引用子对象或查找对象,如果链接实体不在会话高速缓存中,则代理代码将转到数据库并加载链接对象.它使用javassist有效地动态生成对象的子类实现(尽管我认为它也可以配置为使用CGLIB).

如果它没有以这种方式代理,那么实现无缝延迟加载几乎是不可能的.

我不记得我的头脑是否使用预先加载,然后是否会返回自然物体.我通常不建议使用急切加载,尤其是如果你有很多链接子实体,因为它很快就会成为一个巨大的性能瓶颈,因为它会将每个链接对象吸入内存.

此外,如果你需要区分类类型而不是使用obj.getClass(),那么使用Hibernate.getClass(obj)它会返回自然对象类,无论它是否被代理:请参阅这里的Hibernate API Javadocs .

  • 通常,问题是*以这种方式返回的代理*未正确初始化;否则,如果它被正确填充,事情应该会正常进行。有人知道为什么 find 方法可能会返回一个未初始化的代理吗? (2认同)

Luk*_*ski 6

在我看来,这个表达:

hibernateTemplate.find("from User u where u.username = ?", username)
Run Code Online (Sandbox Code Playgroud)

应始终返回 POJO,而不是代理。这是因为标准 HQL/条件返回非代理对象,而是原始实体类的对象。这与惰性关联获取不同:

@Entity
class X {
    @ManyToOne(fetch = FetchType.LAZY)
    private User user;
}
Run Code Online (Sandbox Code Playgroud)

X从这里的数据库获取对象,我们将在X.user字段中有一个惰性代理(代理User实例)。

现在,有时from User where [...]你有 POJO,有时有代理对象。通常这是因为在某些执行中User,首先通过关联从数据库获取对象(from X where [...]在给定的休眠会话中首先调用查询)。已经(代理)User实例后,hibernate 将重用该实例,即使对于像from User where [...].