|
Posted on 2007-11-12 16:29 G_G 閱讀(2072) 評論(3) 編輯 收藏 所屬分類: hibernate
緩存問題:
????
/**
?使用?Query.executeUpdate()?緩存中數據不同步?解決辦法 ?????*??Table?->?T1oo(id,name) ?????*?Table?->?T2oo(id,avg,aid) ?????*?外鍵?T1oo.id->T2oo.aid ?????*??Session.createQuery("delete?T1oo")?->??Query.executeUpdate()? ????
*/
????
public
?
void
?testExecuteUpdate(){ ????????System.out.println(
"
\r\n\r\n********************ExecuteUpdate************************
"
); ????????T1oo?t1oo?
=
?
new
?T1oo(); ????????t1oo.setName(
"
liukaiyi
"
); ???????? ????????HibernateSessionFactory.closeSession(); ???????? ????????Session?session?
=
?HibernateSessionFactory.currentSession(); ????Transaction?tr1?
=
?session.beginTransaction(); ????????
//
t1?成為?持久狀態?一級緩存中?加載
????????session.saveOrUpdate(t1oo);? ????????
//
直接一條語句刪除T1oo,緩存無法同步 ????????
//
一級緩存中還有?t1
????????Query?qu?
=
?session.createQuery(
"
delete?T1oo
"
); ????????
try
?{ ????????????qu.executeUpdate(); ????????}?
catch
?(Exception?e)?{???? ????????????System.out.println(
"
//err:?有級聯?單使用?delete?T1oo?還要delete?T2oo.aid?=?T1oo.id//
"
); ????????????List?list?
=
?session.createQuery(
"
from?T1oo
"
).list(); ????????????
for
(Iterator?it
=
list.iterator();it.hasNext();){ ????????????????Query?t2qu?
=
?session.createQuery(
"
delete?T2oo??where?aid=:id
"
); ????????????????t2qu.setInteger(
"
id
"
,?((T1oo)it.next()).getId().intValue()); ????????????????t2qu.executeUpdate();???????????????? ????????????} ????????????qu.executeUpdate(); ????????} ???????? ????????tr1.commit(); ???????? ????Transaction?tr2?
=
?session.beginTransaction(); ????????
//
這直接通過一級緩存中加載t2,但DB中以沒有此條數據
????????t1oo?
=
?(T1oo)session.load(T1oo.
class
,t1oo.getId()); ????????t1oo.setName(
"
google
"
); ????????
try
?{ ????????????tr2.commit();???? ????????}?
catch
?(Exception?e)?{ ????????????System.out.println(
"
//err:?update(t1oo)->DB?中數據庫中沒有?t1oo?//
"
); ????????} ????????
????????System.out.println(
"
?一級緩存清空前?
"
+
?session.get(T1oo.
class
,t1oo.getId())?); ????????session.evict(t1oo); ????????System.out.println(
"
?一級緩存清空后?
"
+
?session.get(T1oo.
class
,t1oo.getId())?); ???????? ????????
//
不把t1oo?id?為空,否則當在saveOrUpdate時候就會以為是游離態?update了
????????t1oo.setId(
null
); ????????
//
id=null?insert?調用
????????session.saveOrUpdate(t1oo);???????? ????????tr2.commit(); ???????? ????Transaction?tr3?
=
?session.beginTransaction(); ????????session.delete(t1oo); ????????tr3.commit(); ???????? ????????session.close(); ????????HibernateSessionFactory.closeSession(); ???????? ????}
結果是: ********************ExecuteUpdate************************ log4j:WARN No appenders could be found for logger (org.hibernate.cfg.Environment). log4j:WARN Please initialize the log4j system properly. Hibernate: insert into t1oo (name, id) values (?, ?) Hibernate: delete from t1oo //err: 有級聯 單使用 delete T1oo 還要delete T2oo.aid = T1oo.id// Hibernate: select t1oo0_.id as id, t1oo0_.name as name0_ from t1oo t1oo0_ Hibernate: delete from t2oo where aid=? Hibernate: delete from t2oo where aid=? Hibernate: delete from t2oo where aid=? Hibernate: delete from t1oo Hibernate: update t1oo set name=? where id=? //err: update(t1oo)->DB 中數據庫中沒有 t1oo // ?一級緩存清空前 hbn.bean.T1oo@287 Hibernate: select t1oo0_.id as id0_, t1oo0_.name as name0_0_ from t1oo t1oo0_ where t1oo0_.id=? ?一級緩存清空后 null Hibernate: insert into t1oo (name, id) values (?, ?) Hibernate: delete from t1oo where id=?
Get Load 區別 : ?????/**?Get?Load?區別?(在commit前要?session.flush()) ?????*?Table?->?T1oo(id,name) ?????*?1.如果未能發現符合條件的記錄,get方法返回null,而load方法會拋出異常 ?????*?2.Load方法可返回實體的代理類實例,而get方法永遠直接返回實體類。 ?????*?3.load方法可以充分利用內部緩存和二級緩存中的現有數據,而get方法則僅僅在內部緩存中進行數據查找, ?????*?????????????如沒有發現對應數據,將越過二級緩存,直接調用SQL完成數據讀取。? ?????*/ ????public?void?testGetLoad()?throws?Exception?{ ????????System.out.println("\r\n\r\n********************Get<>Load************************"); ????????Session?session?=?HibernateSessionFactory.currentSession(); ????//??數據準備 ????????T1oo?t1oo?=?new?T1oo(); ????????t1oo.setName("liu"); ????Transaction?t1?=?session.beginTransaction(); ????????session.saveOrUpdate(t1oo); ????????//?為什么這會錯? ????????//session.evict(t1oo); ????????//session.flush(); ????????t1.commit(); ????????session.evict(t1oo); ???? ????Transaction?t2?=?session.beginTransaction(); ????????System.out.println("一級緩存是否有t1oo(load)->"+session.contains(t1oo));? ????????//這時候t1oo為?CGlib生成的代理類 ????????t1oo?=?(T1oo)session.load(T1oo.class,t1oo.getId()); ????????System.out.println("?延遲加載出現:select..?t1oo0_.id=??表的其他屬性加載?"); ????????t1oo.setName("load?list"); ????????//后在?update ????????t2.commit(); ????????session.evict(t1oo); ???????? ????Transaction?t3?=?session.beginTransaction(); ????????System.out.println("一級緩存是否有t1oo(get)->"+session.contains(t1oo));? ????????//這時候t1oo為?CGlib生成的代理類 ????????t1oo?=?(T1oo)session.get(T1oo.class,t1oo.getId()); ????????System.out.println("?沒有延遲加載出現"); ????????t1oo.setName("get?list"); ????????//后在?update ????????t3.commit();???? ????????session.evict(t1oo); ???????? ????Transaction?tr3?=?session.beginTransaction(); ????????session.delete(t1oo); ????????tr3.commit(); ???????? ????????session.close(); ????????HibernateSessionFactory.closeSession(); ???????? ????}
結果 ********************Get<>Load************************ Hibernate: insert into t1oo (name, id) values (?, ?) 一級緩存是否有t1oo(load)->false ?延遲加載出現:select.. t1oo0_.id=? 表的其他屬性加載 Hibernate: select t1oo0_.id as id0_, t1oo0_.name as name0_0_ from t1oo t1oo0_ where t1oo0_.id=? Hibernate: update t1oo set name=? where id=? 一級緩存是否有t1oo(get)->false Hibernate: select t1oo0_.id as id0_, t1oo0_.name as name0_0_ from t1oo t1oo0_ where t1oo0_.id=? ?沒有延遲加載出現 Hibernate: update t1oo set name=? where id=? Hibernate: select t2ooset0_.aid as aid1_, t2ooset0_.id as id1_, t2ooset0_.id as id0_, t2ooset0_.avg as avg1_0_, t2ooset0_.aid as aid1_0_ from t2oo t2ooset0_ where t2ooset0_.aid=? Hibernate: delete from t1oo where id=?
Set 集合的識別:
????/**?Set?集合的識別 ?????*?Table?->?T1oo(id,name) ?????*?Table?->?T2oo(id,avg,aid) ?????*?外鍵?T1oo.id->T2oo.aid ?????*?T1oo??<set?name="t2ooSet"?inverse="false"?cascade?=?"all"??> ?????*?T2oo??<many-to-one?name="t1oo"?column="aid"?class="T1oo"?/> ?????*?cascade='insert'?是一定要的 ?????*?????當?T1oo沒有?inverse="true"?主動權的時候,要雙項關聯 ?????*?????t1oo.getT2ooSet().add(t2oo1); ?????*????t1oo.getT2ooSet().add(t2oo2); ?????*????t2oo1.setT1oo(t1oo); ?????*????t2oo2.setT1oo(t1oo); ?????*??要不后sql為: ?????*??Hibernate:?insert?into?t2oo?(avg,?aid,?id)?values?(?,??,??) ?????*????Hibernate:?insert?into?t2oo?(avg,?aid,?id)?values?(?,??,??) ?????*????+----+-----+------+ ?????*????|?id?|?avg?|?aid??| ?????*????+----+-----+------+ ?????*????|??1?|??24?|?NULL?| ?????*????|??2?|??23?|?NULL?| ?????*????+----+-----+------+ ?????*????當?T1oo有?inverse="false"主動權的時候 ?????*??t1oo.getT2ooSet().add(t2oo1); ?????*????t1oo.getT2ooSet().add(t2oo2); ?????*??Sql語句為: ?????*??Hibernate:?insert?into?t1oo?(name,?id)?values?(?,??) ?????*????Hibernate:?insert?into?t2oo?(avg,?aid,?id)?values?(?,??,??) ?????*????Hibernate:?insert?into?t2oo?(avg,?aid,?id)?values?(?,??,??) ?????*????Hibernate:?update?t2oo?set?aid=??where?id=? ?????*????Hibernate:?update?t2oo?set?aid=??where?id=? ?????*????|??3?|??24?|???12?| ?????*????|??4?|??23?|???12?| ?????*????+----+-----+------+ ????*/ ????public?void?testSet(){ ????????System.out.println("\r\n\r\n********************Set************************"); ????????T1oo?t1oo?=?new?T1oo(); ????????t1oo.setName("list"); ???????? ????????T2oo?t2oo1?=?new?T2oo();?t2oo1.setAvg(new?Integer(23)); ????????T2oo?t2oo2?=?new?T2oo();?t2oo2.setAvg(new?Integer(24)); ???????? ???????? ????????Session?session?=?HibernateSessionFactory.currentSession(); ????????Transaction?tr1?=?session.beginTransaction(); ????????session.save(t1oo); ????????t1oo?=?(T1oo)?session.load(T1oo.class,t1oo.getId());
????????t1oo.setT2ooSet(new?HashSet())?; ????????t1oo.getT2ooSet().add(t2oo1); ????????t1oo.getT2ooSet().add(t2oo2); ????????? ????????System.out.println(?t1oo.getT2ooSet().size()+""?);???????? ????????tr1.commit(); ???????? ????????System.out.println(); ????????T2oo?t2oo3?=?new?T2oo();?t2oo3.setAvg(new?Integer(25)); ????????T1oo?t1oo2?=?new?T1oo();?t1oo2.setName("mz"); ????????t2oo3.setT1oo(t1oo2); ???????? ????????Transaction?tr2?=?session.beginTransaction(); ????????session.save(t2oo3); ????????try?{ ????????????tr2.commit();???? ????????}?catch?(Exception?e)?{ ????????????System.out.println("//err:?沒有主動權?cascade?=?'all'?不可以級聯save?t1oo???//"); ????????} ????????session.close(); ????????HibernateSessionFactory.closeSession(); ????} ???
結果是: ********************Set************************ 2 Hibernate: insert into t1oo (name, id) values (?, ?) Hibernate: insert into t2oo (avg, aid, id) values (?, ?, ?) Hibernate: insert into t2oo (avg, aid, id) values (?, ?, ?) Hibernate: update t2oo set aid=? where id=? Hibernate: update t2oo set aid=? where id=?
//err: 沒有主動權 cascade = 'all' 不可以級聯save t1oo?? //
評論
# re: hibernate 部分問題總結——1 回復 更多評論
2007-11-19 20:04 by
不錯,收藏
# re: hibernate 部分問題總結——1[未登錄] 回復 更多評論
2009-02-14 11:23 by
session.close();
HibernateSessionFactory.closeSession();
為什么要調用兩次
# re: hibernate 部分問題總結——1 回復 更多評論
2009-02-16 09:27 by
第一次 session.close(); 為本線程的session關閉
HibernateSessionFactory.closeSession(); 第二次為 全部連接斷開
|