hibernate和其他ORM框架混合使用的异常情况

版本:hibernate-3.3.1.GA  (http://www.findjar.com/index.x网站提供下载)

org.hibernate.Session session;
//query未设置查询缓存,即便如此hibernate还是会利用session级别的缓存。
Query query = session.createQuery("from "+XoooPo.class.getName()
<span style="white-space:pre">					</span>+" a where a.property1Value = 'value1' ");
query.list();</span>

上面是一个伪代码,我们一定期望返回结果中,所有的XoooPo对象的属性property1Value都是"value1"。实际上,如果返回的XoooPo实例A如果之前已经被hibernate当前session非lazy加载了、加载时A.property1Value是“value000"、之后并未对对象A做任何修改、之后使用ibatis对数据库中对象A的字段修改成了value1,这个时间再去做上面代码里面的hibernate查询,很遗憾返回结果中包含了对象A,但是对象A的property1Value又真的不是"value1",仍然是"value000"。这就是一种非常异常的情况了。

跟hibernate代码,行走的堆栈如下

Daemon Thread [http-7002-Processor11] (Suspended)	
	SessionImpl.getEntityUsingInterceptor(EntityKey) line: 514	
	QueryLoader(Loader).getRow(ResultSet, Loadable[], EntityKey[], Object, EntityKey, LockMode[], List, SessionImplementor) line: 1216	
	QueryLoader(Loader).getRowFromResultSet(ResultSet, SessionImplementor, QueryParameters, LockMode[], EntityKey, List, EntityKey[], boolean) line: 603	
	QueryLoader(Loader).doQuery(SessionImplementor, QueryParameters, boolean) line: 724	
	QueryLoader(Loader).doQueryAndInitializeNonLazyCollections(SessionImplementor, QueryParameters, boolean) line: 259	
	QueryLoader(Loader).doList(SessionImplementor, QueryParameters) line: 2228	
	QueryLoader(Loader).listIgnoreQueryCache(SessionImplementor, QueryParameters) line: 2125	
	QueryLoader(Loader).list(SessionImplementor, QueryParameters, Set, Type[]) line: 2120	
	QueryLoader.list(SessionImplementor, QueryParameters) line: 401	
	QueryTranslatorImpl.list(SessionImplementor, QueryParameters) line: 361	
	HQLQueryPlan.performList(QueryParameters, SessionImplementor) line: 196	
	SessionImpl.list(String, QueryParameters) line: 1148	
	QueryImpl.list() line: 102


可以看到其中核心的就是2个类org.hibernate.impl.SessionImpl、org.hibernate.loader.hql.QueryLoader。
简单说明:
hibernate使用query.list()时,将会自动执行session.flush()方法, 将sessin中对象脏数据sql发到数据库,
即便如此,
QueryLoader(Loader).doQuery(SessionImplementor, QueryParameters, boolean) line: 724
去数据库中查询返回结果java.sql.ResultSet后,并没有根据结果马上去组装新的java对象,
而是先从java.sql.ResultSet数据库中组装Hibernate配置java类的主键的序列化对象,之后通过
SessionImpl.getEntityUsingInterceptor(EntityKey) line: 514
取得session中的已经加载过的对象实例(hibernate中通过map<key,object>判断主键是否存在,这就是为什么主键如果是复合主键,要重写equals、hashCode的原因)。


总结hibernate跟其他ORM混合使用的不足:
1,如果session中已经加载过一个对象A,之后不通过session去修改数据库中的属性内容,那么下一此hibernate的查询结果如果主键是对象A的主键,
那么hibernate不会将查询结果数据去更新session中对象A,而是直接使用内存中已有的对象A放到返回结果中。

2,如果hibernate对一个hibernate管理对象做了修改,并且使用了save、saveOrUpdate等之类的持久话语句,但是没有触发session.flush(),那么其他ORM框架直接从数据库中的的DML语句都是跟hibernate有着冲突的。



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值