導航對象樹時,我有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