Hibernate的lazy问题

来源:互联网 发布:java jsonarray 添加 编辑:程序博客网 时间:2024/05/01 00:22

在运行孙卫琴那本书第七章第一个例子的时候,
BusinessServices.java
package mypack;

import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;
public class BusinessService{
  public static SessionFactory sessionFactory;
  static{
     try{
      // Create a configuration based on the properties file we've put
       Configuration config = new Configuration();
       config.addClass(Category.class);
      // Get the session factory we can use for persistence
      sessionFactory = config.configure().buildSessionFactory();
    }catch(Exception e){e.printStackTrace();}
  }

  public void saveFoodCategory() throws Exception{
      Category  foodCategory=new Category("food",null,new HashSet());
      Category  fruitCategory=new Category("fruit",null,new HashSet());
      Category  appleCategory=new Category("apple",null,new HashSet());

      //建立食品类别和水果类别之间的关联关系
      foodCategory.addChildCategory(fruitCategory);
       //建立水果类别和苹果类别之间的关联关系
      fruitCategory.addChildCategory(appleCategory);
       saveOrUpdate(foodCategory);
  }

  public void navigateCategories() throws Exception{
      Category fruitCategory=findCategoryByName("fruit");
      HashSet categories=new HashSet();
      navigateCategories(fruitCategory,categories);
      for (Iterator it = categories.iterator(); it.hasNext();) {
         System.out.println(((Category)it.next()).getName());
      }
  }
  private void navigateCategories(Category category,Set categories){
   if(categories.contains(category)|| category==null)return;
   categories.add(category);

   //遍历父类Category
   navigateCategories(category.getParentCategory(),categories);

   //遍历所有子类Category
   Set childCategories=category.getChildCategories();
   if(childCategories==null)return;

   for (Iterator it = childCategories.iterator(); it.hasNext();) {
         navigateCategories((Category)it.next(),categories);
    }
  }
  public void saveVegetableCategory() throws Exception{
      Category foodCategory=findCategoryByName("food");
      Category vegetableCategory=new Category("vegetable",null,new HashSet());
      foodCategory.addChildCategory(vegetableCategory);
      saveOrUpdate(vegetableCategory);
  }

  public void updateVegetableCategory() throws Exception{
      Category vegetableCategory=findCategoryByName("vegetable");
      vegetableCategory.setName("green vegetable");
      Category tomatoCategory=new Category("tomato",null,new HashSet());
      vegetableCategory.addChildCategory(tomatoCategory);
      saveOrUpdate(vegetableCategory);
  }
  public void saveOrangeCategory() throws Exception{
    Session session = sessionFactory.openSession();
    Transaction tx = null;
    try {
      tx = session.beginTransaction();
      Category fruitCategory=findCategoryByName(session,"fruit");
      Category orangeCategory=new Category("orange",null,new HashSet());
      fruitCategory.addChildCategory(orangeCategory);
      tx.commit();
    }catch (Exception e) {
      if (tx != null) {
        // Something went wrong; discard all partial changes
        tx.rollback();
      }
      throw e;
    } finally {
      // No matter what, close the session
      session.close();
    }
  }
  public void saveOrUpdate(Object object) throws Exception{
    Session session = sessionFactory.openSession();
    Transaction tx = null;
    try {
      tx = session.beginTransaction();
      session.saveOrUpdate(object);
      tx.commit();
    }catch (Exception e) {
      if (tx != null) {
        // Something went wrong; discard all partial changes
        tx.rollback();
      }
      throw e;
    } finally {
      // No matter what, close the session
      session.close();
    }
  }

   private Category findCategoryByName(String name)throws Exception{
    Session session = sessionFactory.openSession();
    Transaction tx = null;
    Category category=null;
    try {
      tx = session.beginTransaction();
      List results=session.createQuery("from Category as c where c.name='"+name+"'").list();
      category=(Category)results.iterator().next();
      tx.commit();

    }catch (Exception e) {
      if (tx != null) {
        // Something went wrong; discard all partial changes
        tx.rollback();
      }
      throw e;
    } finally {
      // No matter what, close the session
      session.close();
    }
    return category;
  }

   private Category findCategoryByName(Session session, String name)throws Exception{
      List results=session.createQuery("from Category as c where c.name='"+name+"'").list();
      return (Category)results.iterator().next();
  }

   public void test() throws Exception{
      //saveFoodCategory();
      //saveOrangeCategory();
      saveVegetableCategory();
      //updateVegetableCategory();
      //navigateCategories();
   }

  public static void main(String args[]) throws Exception {
    new BusinessService().test();
    sessionFactory.close();
  }
}

saveVegetableCategory();方法抛出错误:
org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: mypack.Category.childCategories, no session or session was closed
        at org.hibernate.collection.AbstractPersistentCollection.throwLazyInitializationException(AbstractPersistentCollection.java:358)
        at org.hibernate.collection.AbstractPersistentCollection.throwLazyInitializationExceptionIfNotConnected(AbstractPersistentCollection.java:350)
        at org.hibernate.collection.AbstractPersistentCollection.initialize(AbstractPersistentCollection.java:343)
        at org.hibernate.collection.AbstractPersistentCollection.write(AbstractPersistentCollection.java:183)
        at org.hibernate.collection.PersistentSet.add(PersistentSet.java:165)
        at mypack.Category.addChildCategory(Category.java:80)
        at mypack.BusinessService.saveVegetableCategory(BusinessService.java:66)
        at mypack.BusinessService.test(BusinessService.java:152)
        at mypack.BusinessService.main(BusinessService.java:158)
Exception in thread "main"
但是我的配置文件里面在-many-to-one中已经加入了lazy="false"了。
Category.hbm.xml
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping
PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping >
  <class name="mypack.Category" table="CATEGORIES"  >
    <id name="id" type="long" column="ID">
      <generator class="increment"/>
    </id>
    <property name="name" type="string" >
        <column name="NAME" length="15" />
    </property>
    <set  name="childCategories"  cascade="save-update" inverse="true">
        <key column="CATEGORY_ID" />
        <one-to-many class="mypack.Category"  />
     </set>  

   <many-to-one  name="parentCategory"  column="CATEGORY_ID" class="mypack.Category"
        cascade="none"
        lazy="false"     />
  </class>

</hibernate-mapping>
为什么还是出现延迟初始化的错误呢!
因为lazy应该放到set里,而不是many-to-one里。该了就好了!! 发现网上很多人问这个问题。