Hibernate没有加载关联的对象

时间:2011-01-05 16:50:57

标签: java hibernate orm

我正在尝试加载一个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());

2 个答案:

答案 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()则不然。