我在一个域对象上有一个属性,该属性在多对一元素中声明。此属性的基本语法如下所示:
<many-to-one name="propertyName" class="propertyClass" fetch="select" not-found="ignore" lazy="proxy" />
现在,我们的想法是让Hibernate不急切地获取这个属性。它可能为null,因此设置了未找到的忽略。
但是,Hibernate在加载包含此关联的类时,会在加载父类时自行加载实际的类(甚至不是代理)实例。由于某些属性的大小超过1MB,因此占用了大量的堆空间。
但是,如果not-found设置为异常(或默认为异常),则具有此属性的父类会加载代理!
如何在不加载代理的情况下阻止hibernate,同时仍允许此属性为空?
我发现lazy = no-proxy,但是文档讨论了某种字节码修改,并没有详细说明。有人可以帮助我吗?
如果重要的话,它是Hibernate的Java版本,它至少是版本3(如果它有帮助我可以查看实际版本,但现在它是Hibernate 3+)。
我之前没有说明,但Java版本是1.4。因此,不支持Java注释。
答案 0 :(得分:9)
如果关联的另一端可以是 null ,我相信hibernate必须查询关联结束,以确定它是否应该使用代理(如果另一个则不需要代理)结束是 null )。我现在找不到对此的引用,但我记得在某处读过它。
为了提供字段的延迟加载,文档引用了构建时字段的字节码增强功能:Using lazy property fetching。这是一段摘录:
Hibernate3支持延迟抓取 个人财产。这个 优化技术也是已知的 作为获取组。请注意这一点 主要是营销功能,如 练习,优化行读取很多 比优化更重要 列读。但是,只能加载 类的某些属性可能是 遗留下来的极端情况下很有用 表有数百列和 数据模型无法改进。
懒惰的属性加载需要 构建时间字节码检测!如果 你的持久化课程不是 增强,Hibernate将默默无闻 忽略懒惰的属性设置和下降 回到即时提取。
答案 1 :(得分:2)
我发现懒惰=没有代理,但是 文档谈论某种 字节码修改,不去 任何细节。有人能帮我吗 出?
我假设您正在使用ANT来构建项目。
<property name="src" value="/your/src/directory"/><!-- path of the source files -->
<property name="libs" value="/your/libs/directory"/><!-- path of your libraries -->
<property name="destination" value="/your/build/directory"/><!-- path of your build directory -->
<fileset id="applibs" dir="${libs}">
<include name="hibernate3.jar" />
<!-- include any other libraries you'll need here -->
</fileset>
<target name="compile">
<javac srcdir="${src}" destdir="${destination}" debug="yes">
<classpath>
<fileset refid="applibs"/>
</classpath>
</javac>
</target>
<target name="instrument" depends="compile">
<taskdef name="instrument" classname="org.hibernate.tool.instrument.javassist.InstrumentTask">
<classpath>
<fileset refid="applibs"/>
</classpath>
</taskdef>
<instrument verbose="true">
<fileset dir="${destination}">
<!-- substitute the package where you keep your domain objs -->
<include name="/com/mycompany/domainobjects/*.class"/>
</fileset>
</instrument>
</target>
答案 2 :(得分:2)
确保你的课程不是最终的!
答案 3 :(得分:0)
如果您通过控制器将hibernate对象从模型传递到视图,请不要!
而是创建一个“快照对象”来存储要传递给视图并显示的Hibernate对象的值。
<强>为什么吗 代理仍可以在控制器中检索值...但是当您将代理/对象传递给视图时,它不再能够检索值,因为事务已经结束。这就是为什么我建议我上面提到的。
答案 4 :(得分:0)
使用Hibernate注释时,在关联上放置@ManyToOne(fetch = FetchType.LAZY),完成你想要的。您是否尝试过设置fetch =“lazy”以查看是否有效?
答案 5 :(得分:0)
@Miguel Ping:
我认为你所指的页面是[http://www.hibernate.org/162.html]。据我所知,在一对一的情况下需要额外的SELECT,其中不存在外键。设置constrained="true"
告诉Hibernate,另一端始终存在,不需要额外的SELECT。
因此,对于外键所在的多对一方,没有必要这么做
执行另一个SELECT,因为FK的值告诉另一端是否存在或null
。至少,这就是我理解的方式。
迄今为止的理论。代理在外键/多对一方面为我工作。用于关联的映射是:
<many-to-one name="haendler" column="VERK_HAENDLOID" lazy="proxy" />
但代理对我来说并不适用于使用给定URL(constrained="true"
)所描述的映射的一对一方面。嗯,我想我会为此提出一个问题。 ; - )