如何阻止Hibernate急切地获取多对一关联对象

我在一个域对象上有一个属性,该属性在多对一元素中声明。 此属性的基本语法如下所示:

 

现在,我们的想法是让Hibernate不急切地获取这个属性。 它可能为null,因此设置了未找到的忽略。

但是,Hibernate在加载包含此关联的类时,会在加载父类时自行加载实际的类(甚至不是代理)实例。 由于某些属性的大小超过1MB,因此占用了大量的堆空间。

但是,如果not-found设置为exception(或默认为exception),则具有此属性的父类会加载代理!

如何在不加载代理的情况下阻止hibernate,同时仍然允许此属性为null?

我发现lazy = no-proxy,但是文档讨论了某种字节码修改,并没有详细说明。 有人可以帮我吗?

如果重要的话,它是Hibernate的Java版本,它至少是版本3(如果它有帮助我可以查看实际版本,但现在它是Hibernate 3+)。

我之前没有说明,但Java版本是1.4。 因此,不支持Java注释。

如果关联的另一端可以为null ,我相信hibernate必须查询关联结束以确定它是否应该使用代理(如果另一端为null则不需要代理)。 我现在找不到对此的引用,但我记得在某处读过它。

为了提供字段的延迟加载,文档引用了构建时字段的字节码增强: 使用延迟属性提取 。 这是一段摘录:

Hibernate3支持延迟获取各个属性。 此优化技术也称为提取组。 请注意,这主要是一种营销function,因为在实践中,优化行读取比优化列读取更重要。 但是,在极端情况下,只有加载某些类的属性才有用,因为遗留表有数百列,并且数据模型无法改进。

延迟属性加载需要构建时字节码检测! 如果您的持久化类没有得到增强,Hibernate将默默地忽略惰性属性设置并回退到立即获取。

我发现lazy = no-proxy,但是文档讨论了某种字节码修改,并没有详细说明。 有人可以帮我吗?

我假设你正在使用ANT来构建你的项目。

                            

确保你的课程不是最终的!

如果您通过控制器将hibernate对象从模型传递到视图,请不要!

而是创建一个“快照对象”来存储要传递给视图并显示的Hibernate对象的值。

为什么? 代理仍可以在控制器中检索值…但是当您将代理/对象传递给视图时,它不再能够检索值,因为事务已经结束。 这就是我提出上述内容的原因。

使用Hibernate注释时,在关联上放置@ManyToOne(fetch = FetchType.LAZY),即可完成您想要的操作。 您是否尝试过设置fetch =“lazy”以查看是否有效?

@Miguel Ping:我认为您所指的页面是[ http://www.hibernate.org/162.html%5D 。 据我所知,在一对一的情况下需要附加的SELECT,其中不存在外键。 设置constrained="true"告诉Hibernate,另一端始终存在,不需要额外的SELECT。

因此,对于外键所在的多对一方,不需要执行另一个SELECT,因为FK的值告诉另一端是否存在或为null 。 至少,这是我理解它的方式。

到目前为止理论。 代理在外键/多对一方面为我工作。 使用的关联映射是:

但代理对我来说并不适用于使用像给定URL( constrained="true" )所描述的映射的一对一方面。 嗯,我想我会为此提出一个问题。 😉