2008年7月26日 星期六

hibernate LazyInitializationException

hibernate 3 預設有啟動LazyInitialization
在Session.
load(Class theClass,Serializable id)時
還不會將資料庫中的資料載入到物件中,一直要到物件屬性被改變時才會載入,
但修改物件時Session必須處於open狀態,否則會丟出LazyInitializationException
如果在Session關閉後才要使用物件則可以使用Hibernate.initialize(rec_obj);
來先行載入資料庫的資料到物件中
如:
Session session = HibernateUtil.getSessionFactory().openSession();
User user = (User) session.load(User.class, new Integer(1));
Hibernate.initialize(user);

session.close();

Hibernate的Session物件有兩個:
org.hibernate.Session 及 org.hibernate.classic.Session
classic版是為了相容於Hibernate 2.x的物件,已半棄用,建議新的開發要使用
org.hibernate.Session

使用Hql進行查詢時可以一次查詢多個資料表的物件,只要把資料TO物件extends/implements同一個class/interface即可,如:
Man implements Human ...
Woman implements Human ...
同時查找Man 及 Woman的資料:
Session.find("from Human ...");

透過ThreadLocal讓多個Thread各自管理自己的Session物件範例:
public class HibernateUtil {
public static final SessionFactory sessionFactory;
static {
try {
sessionFactory = new Configuration().configure().buildSessionFactory();
} catch (Throwable ex) {
throw new ExceptionInInitializerError(ex);
}
}
public static final ThreadLocal session = new ThreadLocal();
public static Session currentSession() throws HibernateException {
Session s = session.get();
if(s == null) {
s = sessionFactory.openSession();
session.set(s);
}
return s;
}
public static void closeSession() throws HibernateException {
Session s = session.get();
if(s != null) {
s.close();
}
session.set(null);
}
}

沒有留言:

張貼留言