我正在尝试加载一个hibernate对象ForumMessage但是它包含另一个对象用户和Users对象没有被加载。
我的ForumMessage映射文件:
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<!-- Generated Jan 4, 2011 10:10:29 AM by Hibernate Tools 3.4.0.Beta1 -->
<hibernate-mapping>
<class name="com.BiddingSystem.Models.ForumMessage" table="FORUMMESSAGE">
<id name="ForumMessageId" type="long">
<column name="FORUMMESSAGEID" />
<generator class="native" />
</id>
<property name="ForumMessage" type="java.lang.String">
<column name="FORUMMESSAGE" />
</property>
<many-to-one name="User" class="com.BiddingSystem.Models.Users" fetch="join">
<column name="UserId" />
</many-to-one>
<property name="DatePosted" type="java.util.Date">
<column name="DATEPOSTED" />
</property>
<many-to-one name="Topic" class="com.BiddingSystem.Models.ForumTopic" fetch="join">
<column name="TopicId" />
</many-to-one>
</class>
</hibernate-mapping>
我正在使用以下代码:
Session session = gileadHibernateUtil.getSessionFactory().openSession();
SQL="from ForumMessage";
System.out.println(SQL);
Query query=session.createQuery(SQL);
System.out.println(query.list().size());
return new LinkedList <ForumMessage>(query.list());
答案 0 :(得分:3)
<many-to-one name="User" class="com.BiddingSystem.Models.Users" fetch="join" lazy="false">
您还需要添加lazy =“false”。
答案 1 :(得分:2)
您可以将lazy="false"
添加到多对一映射中,该映射将在加载ForumMessage时加载用户。或者,您可以使用Hibernate.initialize()初始化用户列表。请确保在关闭会话之前执行此操作。
Session session = gileadHibernateUtil.getSessionFactory().openSession();
string sql = "from ForumMessage";
Query query = session.createQuery(sql);
List results = query.list()
for(ForumMessage message : results)
{
Hibernate.initialize(message.User);
}
return new LinkedList <ForumMessage>(results);
如果您有需要,您应该只执行其中一项。 Hibernate默认延迟加载对象以避免对数据库进行不必要的调用。例如:
public LinkedList getMessages()
{
//It's assumed the session is opened and closed elsewhere.
string sql = "from ForumMessage";
Query query = session.createQuery(sql);
List results = query.list();
//The overhead of extra calls to the database occur here.
//This would have a similar impact if lazy load is set to false.
for(ForumMessage message : results)
{
Hibernate.initialize(message.User);
}
return new LinkedList <ForumMessage>(results);
}
public void printMessages()
{
LinkedList messages = getMessages();
for(ForumMessage message : messages)
{
System.out.println(message.ForumMessage);
}
}
在上面的代码示例中,加载所有Users对象会产生开销,但从不使用这些对象。如果使用Hibernate的延迟加载,则不会产生额外的开销。在以下示例中,在使用列表之前,不会加载用户列表。这样,在实际需要数据之前,不会对数据库进行调用。
public LinkedList getMessages()
{
//It's assumed the session is opened and closed elsewhere.
string sql = "from ForumMessage";
Query query = session.createQuery(sql);
List results = query.list();
return new LinkedList <ForumMessage>(results);
}
public void printMessages()
{
LinkedList messages = getMessages();
for(ForumMessage message : messages)
{
//Hibernate will load the users objects here when they are accessed.
for(Users user : message.User)
{
System.out.println(user);
}
}
}
在延迟加载全部加载时要注意的一点必须在活动会话中完成。如果您没有活动会话,并且尝试访问尚未加载的内容,Hibernate将抛出LazyInitializationException
。
此外,使用Hibernate的延迟加载功能更符合持久性无知的概念,而使用Hibernate.initialize()则不然。