如何避免在 Hibernate 中获取 javassist 惰性实体代理实例

Posted

技术标签:

【中文标题】如何避免在 Hibernate 中获取 javassist 惰性实体代理实例【英文标题】:how to avoid getting javassist lazy Entity proxy instances in Hibernate 【发布时间】:2012-12-11 00:44:10 【问题描述】:

为了避免 Hibernate 给我懒惰的 javassist 实例代理而不是真正的实体,我需要做些什么改变?

更新:我正在使用 Spring 3.x 和 Hibernate 4.x

我用来加载实体的 API 是 org.hibernate.internal.SessionImpl#load(Person.class, Id) 并且映射很简单:

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
    "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
    "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">

<hibernate-mapping package="org.perfectjpattern.example.model">
<class name="Person" table="PERSON_" >
    <id name="id">
        <generator class="native"></generator>
    </id>
    <property name="name" update="false" />
    <property name="age" update="true" />
</class>

<query name="Person.findByName">
    <![CDATA[select p from Person p where p.name = ? ]]>
</query>

<query name="Person.findByAge">
    <![CDATA[select p from Person p where p.age = :Age ]]>
</query>
</hibernate-mapping>

【问题讨论】:

使用急切而不是延迟加载。 我可以想象,但是具体什么地方需要配置,这就是OP 如果您向我们展示您的映射实体之一,我们可以为您提供帮助。 几乎 100% 的时间您都想这样做,但这是解决您遇到的问题的错误方法。您可以考虑寻求帮助来解决您的实际问题。 【参考方案1】:

您可以在session.load(id) 之后使用Hibernate.initialize(obj)

这个方法可以立即初始化你的obj。

【讨论】:

...基本上是using session.get()的更复杂更慢的版本。 您可以在需要时初始化您的 obj,而不是总是初始化它。【参考方案2】:

实际上只需将映射更改为(参见default-lazy="false")即可解决:

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">

<hibernate-mapping package="org.perfectjpattern.example.model" default-lazy="false">

【讨论】:

这非常危险,因为它将所有实体和集合都设置为非惰性,这意味着您很容易意外地将整个数据库加载到内存中。 感谢您提出这个问题,但是,正如您在 OP 中所指出的那样,我的映射中只定义了一个实体。在我的用例中,我还 load 仅一个元素(按 ID)。如果我维护一个更大的项目,每个实体都会有自己的映射文件,我可以在其中决定加载策略应该是什么。还有另一方面,对于不同的用例,我必须调用 loadget 从代码可重用性的角度来看这不是一件好事。【参考方案3】:

使用get() 而不是load()。

【讨论】:

+1 以获得更多细节,但我认为load 会更灵活,因为在其他情况下我可能会选择延迟加载。我可以通过这种方式分别为每个实体配置它。 您的应用程序应该选择何时急切地获取东西,何时不急切地获取东西。 IE。必要时使用 get(),其他时候使用 load()。 但还要注意,如果您的应用程序确实需要意识到这一点,那么您几乎可以肯定做错了什么。延迟加载被设计成透明的。

以上是关于如何避免在 Hibernate 中获取 javassist 惰性实体代理实例的主要内容,如果未能解决你的问题,请参考以下文章

如何避免 Hibernate ValidationException 上的自动实体更新

如何避免两个不同的线程从DB中读取相同的行(Hibernate和Oracle 10g)

如何配置 Hibernate Envers 以避免实体修订查询中的某些集合(连接表)

Hibernate使用中防止SQL注入的几种方案

如何通过Hibernate即时获取更新的对象?

如何在 Hibernate 中使用加入 Java 程序?