2011-01-05 80 views
3

我想加载一个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> 

和我使用的follwing代码:

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

你能显示相应的表格定义吗? – jaydel 2011-01-05 17:13:01

+0

我相信这是Hibernate的懒加载.. 在您尝试使用它之前不会加载该对象 尝试从“ForumMessage”链接列表访问用户对象。 – exiter2000 2011-01-05 17:14:05

回答

3
<many-to-one name="User" class="com.BiddingSystem.Models.Users" fetch="join" lazy="false"> 

您需要添加懒= “假” 的可能。

+0

谢谢,它的作品! – Noor 2011-01-05 18:01:41

+0

公顷,在2017年采取了你的建议,它的工作:) – SoltanG 2017-02-28 02:25:42

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()不会。

+0

再次 - 在2017年采取了这个建议,它的工作:) – SoltanG 2017-02-28 02:25:57