Java Hibernate 延迟加载不适用于多对一映射
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/25916563/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Hibernate lazy loading not work with many-to-one mapping
提问by Ousmane MINTE
I have problem of performance in my many-to-one mapping. When I debug the SQL query in log file the principal query it's ok, but after i have other query representing many-to-one object mapping.
我的多对一映射存在性能问题。当我在日志文件中调试 SQL 查询时,主体查询没问题,但是在我有其他查询表示多对一对象映射之后。
Entity.hbm.xml :
实体.hbm.xml :
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd" >
<hibernate-mapping>
<class name="com.omb.database.mapping.MyEntity" table="MY_ENTITY">
<id name="id" type="java.lang.Integer">
<column name="ENTITY_ID"/>
<generator class="sequence">
<param name="sequence">SEQ_MY_ENTITY</param>
</generator>
</id>
<property name="prop1" type="string" column="PROP1" />
<many-to-one name="object1" column="OBJECT1_ID" class="com.omb.database.mapping.Object1" />
<many-to-one name="object2" column="OBJECT2_ID" class="com.omb.database.mapping.Object2" />
</class>
</hibernate-mapping>
Object1.hbm.xml :
Object1.hbm.xml :
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd" >
<hibernate-mapping default-lazy="true">
<class name="com.omb.database.mapping.Object1" table="TABLE_OBJECT_1">
<id name="id" type="java.lang.Integer" column="OBJECT1_ID" />
<property name="label" type="string" column="LABEL_OBJECT_1" length="15" />
</class>
</hibernate-mapping>
Object2.hbm.xml :
Object2.hbm.xml :
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd" >
<hibernate-mapping default-lazy="true">
<class name="com.omb.database.mapping.Object2" table="TABLE_OBJECT_2">
<id name="id" type="java.lang.Integer" column="OBJECT2_ID" />
<property name="label" type="string" column="LABEL_OBJECT_2" length="15" />
</class>
</hibernate-mapping>
Query HBM :
查询 HBM :
public List<Entity> findByObject1Id(Integer object1Id) throws DataAccesException {
List<Entity> results = null;
try {
Query query = this.getSession().createQuery(
"from Entity ent where ent.object1.id = :object1Id");
query.setParameter("object1Id", object1Id);
results = query.list();
} catch (HibernateException hbe) {
throw new DataAccesException(hbe);
}
return results;
}
in pom.xml
在 pom.xml 中
<!-- Hibernate 3 -->
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate</artifactId>
<version>3.2.6.ga</version>
<exclusions>
<exclusion>
<groupId>javax.transaction</groupId>
<artifactId>jta</artifactId>
</exclusion>
<exclusion>
<groupId>net.sf.ehcache</groupId>
<artifactId>ehcache</artifactId>
</exclusion>
<exclusion>
<groupId>asm</groupId>
<artifactId>asm-attrs</artifactId>
</exclusion>
</exclusions>
</dependency>
采纳答案by Petar Butkovic
Did you try with FetchMode.SELECT, like this;
您是否尝试过像这样使用 FetchMode.SELECT?
<many-to-one name="object1" column="OBJECT1_ID" class="com.omb.database.mapping.Object1" fetch="select" />
回答by Radim K?hler
Your mapping seems to be ok. As documented here 5.1.1. Entity
你的映射似乎没问题。如此处记录的5.1.1。实体
The <class>
attribute lazyis by default true
该 <class>
属性懒惰是默认为true
- lazy (optional): lazy fetching can be disabled by setting lazy="false".
- 懒惰(可选):可以通过设置 lazy="false" 来禁用懒惰提取。
The same for <many-to-one>
: 5.1.7.1. Using a foreign key or an association tablelazyattribute:
同样适用于<many-to-one>
:5.1.7.1。使用外键或关联表惰性属性:
- lazy (optional - defaults to proxy): by default, single point associations are proxied.
lazy="no-proxy"
specifies that the property should be fetched lazily when the instance variable is first accessed. This requires build-time bytecode instrumentation.lazy="false"
specifies that the association will always be eagerly fetched.
- 懒惰(可选 - 默认为代理):默认情况下,单点关联被代理。
lazy="no-proxy"
指定在第一次访问实例变量时应该延迟获取属性。这需要构建时字节码检测。lazy="false"
指定将始终急切地获取关联。
So, where is the issue?
那么,问题出在哪里呢?
I would say in your debug window. Because you do have a reference to your list, and you are watching the result - in the moment it is executed - the reference is also loaded. Lazily - but loaded. That's in fact what we want. Proxy - when firstly tuched - is forcing the load.
我会在您的调试窗口中说。因为您确实有对列表的引用,并且您正在观察结果 - 在它被执行的那一刻 - 引用也被加载。懒惰 - 但加载。这实际上就是我们想要的。代理 - 第一次启动时 - 正在强制加载。
Try to remove it from watch. Or close the session and then put it in the watch... You should see, taht the query used above - is not loading references... only when really accessed... even via debug window
尝试将其从手表中删除。或关闭会话,然后将其放入手表中...您应该看到,上面使用的查询 - 没有加载引用...仅在真正访问时...即使通过调试窗口