|
Posted on 2007-11-12 16:29 G_G 阅读(2065) 评论(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(); 第二次为 全部连接断开
|