hibernate忽略fetch=";加入;使用迭代器导航对象树时在集合上
我有一个论坛,有1..n个成员,每个成员有1..n篇文章,因此这是我的映射:hibernate忽略fetch=";加入;使用迭代器导航对象树时在集合上,hibernate,fetch,Hibernate,Fetch,我有一个论坛,有1..n个成员,每个成员有1..n篇文章,因此这是我的映射: <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"> <hibernate-m
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping auto-import="true">
<class name="Forum" table="forum">
<id name="id">
<generator class="identity" />
</id>
<property name="name" />
<set name="members" table="members" inverse="true">
<key column="forum_id" not-null="true" />
<one-to-many class="Member" />
</set>
</class>
<class name="Article" table="article">
<id name="id">
<generator class="identity" />
</id>
<property name="title" />
<many-to-one name="member" column="member_id" class="Member"
not-null="true">
</many-to-one>
</class>
<class name="Member" table="member">
<id name="id">
<generator class="identity" />
</id>
<property name="name" />
<many-to-one name="forum" column="forum_id" class="Forum"
not-null="true">
</many-to-one>
<set name="articles" fetch="join" table="articles"
inverse="true">
<key column="member_id" not-null="true" />
<one-to-many class="Article" />
</set>
</class>
</hibernate-mapping>
这一次成功了:
public void testFetchJoinByGraphNavigation ( )
{
Member member = (Member) repository.findById(Member.class, memberId);
assertEquals(member.getName(), "firstMember");
endTransaction();
assertEquals(1, member.getArticles().size());
}
唯一的区别是加载成员的方式
hibernate参考说明:
“映射文档中定义的获取策略影响:
package hibernate.fetch;
import org.springframework.orm.hibernate3.support.HibernateDaoSupport;
public class Repository extends HibernateDaoSupport
{
public Object findById ( Class clazz, Long objectId )
{
return getHibernateTemplate().load(clazz, objectId);
}
public void save ( Object object )
{
getHibernateTemplate().saveOrUpdate(object);
}
}
这是我的pom.xml:
<?xml version="1.0" encoding="UTF-8"?>
<project>
<modelVersion>4.0.0</modelVersion>
<groupId>hibernate-fetch</groupId>
<artifactId>hibernate-fetch</artifactId>
<version>1.0-SNAPSHOT</version>
<build>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.5</source>
<target>1.5</target>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-eclipse-plugin</artifactId>
<configuration>
<downloadSources>true</downloadSources>
<ajdtVersion>1.5</ajdtVersion>
</configuration>
</plugin>
</plugins>
</build>
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring</artifactId>
<version>2.5.6</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-orm</artifactId>
<version>2.5.6</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
<version>3.3.1.GA</version>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.14</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>1.5.2</version>
</dependency>
<dependency>
<groupId>javassist</groupId>
<artifactId>javassist</artifactId>
<version>3.8.0.GA</version>
</dependency>
<dependency>
<groupId>postgresql</groupId>
<artifactId>postgresql</artifactId>
<version>8.2-504.jdbc3</version>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.13</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>2.5.6</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>jmock</groupId>
<artifactId>jmock</artifactId>
<version>1.1.0</version>
<scope>test</scope>
</dependency>
</dependencies>
</project>
}
我真的不明白 这两种情况真的很不一样 在失败的示例中,您正在加载论坛实体,它有一个延迟初始化的成员实体集合。当您尝试在集合中导航时,它会失败,因为集合是惰性集合,并且在会话关闭之前您没有加载集合 在工作示例中,这不是“图形导航”,而是直接加载成员实体,因此不涉及延迟加载语义
您所指的文档涉及到第一种情况的不同措辞方式,在这种情况下,在成员集上指定渴望加载可以防止失败。这两种情况实际上是完全不同的 在失败的示例中,您正在加载论坛实体,它有一个延迟初始化的成员实体集合。当您尝试在集合中导航时,它会失败,因为集合是惰性集合,并且在会话关闭之前您没有加载集合 在工作示例中,这不是“图形导航”,而是直接加载成员实体,因此不涉及延迟加载语义
您所引用的文档涉及到第一种情况的不同措辞方式,在这种情况下,在成员集上指定渴望加载可以防止失败。您是否在findById(…)方法中使用HQL?使用HQL时,Hibernate不尊重您的获取/加入设置;您需要使用一个HQL子句,如“left join fetch”,以便急切地加载关联。此外,如果您是Hibernate2.x,您将无法在一个查询中急切地获取多个集合。请参阅hibernate网站上的高级问题常见问题解答:
您是否在findById(…)方法中使用HQL?使用HQL时,Hibernate不尊重您的获取/加入设置;您需要使用一个HQL子句,如“left join fetch”,以便急切地加载关联。此外,如果您是Hibernate2.x,您将无法在一个查询中急切地获取多个集合。请参阅hibernate网站上的高级问题常见问题解答:
我认为这是一个hibernate文档错误 参考文件中指出: “另一方面,您可以使用join 获取,本质上是非惰性的” 在JPwH的书中,它说,p。579 因此,fetch=“join”将禁用懒惰 装载 这不是真的。当我将我的文章映射到
<set name="articles" fetch="join" lazy="false" table="articles" inverse="true">
两个测试都可以正常运行,但第二个测试在加载成员时不运行联接
因此,我的结论是:使用连接的即时抓取策略不会影响代理初始化,也不会禁用延迟加载。这与hibernate文档形成对比。我认为这是一个hibernate文档错误 参考文件中指出: “另一方面,您可以使用join 获取,本质上是非惰性的” 在JPwH的书中,它说,p。579 因此,fetch=“join”将禁用懒惰 装载 这不是真的。当我将我的文章映射到
<set name="articles" fetch="join" lazy="false" table="articles" inverse="true">
两个测试都可以正常运行,但第二个测试在加载成员时不运行联接
因此,我的结论是:使用连接的即时抓取策略不会影响代理初始化,也不会禁用延迟加载。这与hibernate文档形成对比。实际上,我不认为在这种情况下是这样的。他在调用
endTransaction()
之前获取“member”,因此推测它仍在会话中。失败的是随后的member.getArticles().size()
调用。更令人费解的问题是为什么第二次测试成功;既然fetch=“join”
不应该覆盖默认的lazy=“true”
设置,它似乎也应该失败。我猜它是先前加载并初始化的“member”,它是从会话中获得的。事实上,我不认为这在本例中是正确的。他在调用endTransaction()
之前获取“member”,因此推测它仍在会话中。失败的是随后的member.getArticles().size()
调用。更令人费解的问题是为什么第二次测试成功;既然fetch=“join”
不应该覆盖默认的lazy=“true”
设置,它似乎也应该失败。我猜它以前是从会话中加载并初始化的“成员”。请看我的编辑1:我不使用HQL,而是使用springs hibernateTemplate中的标准会话方法。我知道HQLOk的“限制”,抱歉没有太多帮助=(请看我的编辑1:我不使用HQL,而是使用springs hibernateTemplate的标准会话方法。我知道HQLOk的“限制”,抱歉没有太多帮助=(这并不是那么简单,fetch/join行为取决于您请求对象的方式,例如,您是否使用HQL、Criteria API、session.get()等。hibernate文档说,延迟加载被fetch join破坏,因此它应该会影响
<set name="articles" fetch="join" lazy="false" table="articles" inverse="true">