导航对象树时,我有1..1成员各有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-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>
现在我有两个测试:
这一个与LazyInitializationException中失败:
public void testFetchJoinByIteratorNavigation ()
{
Forum forum = (Forum) repository.findById(Forum.class, forumId);
Member member = forum.getMembers().iterator().next();
assertEquals(member.getName(), "firstMember");
endTransaction();
assertEquals(1, member.getArticles().size());
}
这一个成功:
唯一的区别是我加载成员的方式。
Hibernate参考表示:
“的映射文档中定义的抓取策略影响:
- 通过get检索()或负载()
- 检索这种情况发生隐式时的关联是导航
- 条件查询
- HQL查询是否使用子查询获取“
的后续测试是壳体1(通过get检索()或负载()) 失败测试是壳体2 IMHO
为什么“forum.getMembers()。下一个迭代()()。 “不加载所有成员的文章?
编辑1:
这是我的仓库:
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>
编辑2: 这是我的测试案例:
package hibernate.fetch;
import org.springframework.test.AbstractTransactionalSpringContextTests;
public class ForumTest extends AbstractTransactionalSpringContextTests
{
private Repository repository;
private Long memberId;
private Long forumId;
private String name = "test";
@Override
protected String[] getConfigLocations ()
{
return new String[] { "applicationContext.xml" };
}
@Override
protected void onSetUpBeforeTransaction () throws Exception
{
System.out.println(">> preparing Test");
Forum forum = new Forum();
forum.setName(name);
repository.save(forum);
forumId = forum.getId();
Member member = new Member();
member.setName(name);
forum.addMember(member);
repository.save(member);
memberId = member.getId();
Article article = new Article();
article.setTitle(name);
member.addArticle(article);
repository.save(article);
super.onSetUpBeforeTransaction();
System.out.println(">> Test prepared");
}
public void testFetchJoinByGraphNavigation ()
{
System.out.println(">> testFetchJoinByGraphNavigation");
Member member = (Member) repository.findById(Member.class, memberId);
assertEquals(member.getName(), name);
endTransaction();
assertEquals(1, member.getArticles().size());
}
public void testFetchJoinByIteratorNavigation ()
{
System.out.println(">> testFetchJoinByIterationNavigation");
Forum forum = (Forum) repository.findById(Forum.class, forumId);
Member member = forum.getMembers().iterator().next();
assertEquals(member.getName(), name);
endTransaction();
// throws LazyInitializationException because articles were NOT loaded
assertEquals(1, member.getArticles().size());
}
public Repository getRepository ()
{
return repository;
}
public void setRepository (Repository repository)
{
this.repository = repository;
}
}
我真的不明白!
这并不那么简单,取/连接行为取决于你如何询问对象,例如你是否使用HQL,Criteria API,session.get()等 – skaffman 2009-09-28 12:13:18
休眠文档说,延迟加载与加入连接,所以它应该影响对象也加载 但如果你明白它..你能解释为什么grapgh没有加载?我没有使用HQL或Criteria Api,只是session.get()和导航对象树。 – Janning 2009-09-29 10:09:44