MDA/MDD/TDD/DDD/DDDDDDD
posts - 536, comments - 111, trackbacks - 0, articles - 0
  BlogJava :: 首页 :: 新随笔 :: 联系 :: 聚合  :: 管理

hibernate问题

Posted on 2007-09-28 03:51 leekiang 阅读(627) 评论(0)  编辑  收藏 所属分类: hibernate
1,get一个对象并打算修改这个对象时,hibernate会判断该对象的属性值是否有变动,如果没有任何变动,hibernate不会执行update语句。在同时修改页面上的多条记录时可发现这一点。

2,执行以下语句时hibernate3.0.5会报错,而3.2不会
sql="select 1+1 from dual";
session.createSQLQuery(sql).uniqueResult()
报错:addScalar() or addEntity() must be called on a sql query before executing the query.

3,<many-to-one> 的lazy设置为true时,get子对象不会把该父对象抓过来,但可以手动写代码抓取父对象
如 Son son =(Son)this.getHibernateTemplate().get(Son.class, id);
       然后执行 son.getParent().getName();
   这样不仅仅会抓取到name,其他所有的属性如age,sex等都会取到,即用p.getParent().getAge()达到了同样的效果,后台都执行了select * from parent where id=?   注意用p.getParent()仅能得到parent的id.
   这时debug查看parent对象的内存快照,看到的是一个用cglib实现的代理对象,
Hibernate通过使用CGLIB,来实现动态构造一个目标对象的代理类对象,并且在代理类对象中包含目标对象的所有属性和方法,而且所有属性均被赋值为null。通过调试器显示的内存快照,我们可以看出此时真正的User对象,是包含在代理对象的CGLIB$CALBACK_0.target属性中,当调用son.getName()方法,这时通过CGLIB赋予的回调机制,实际上调用CGLIB$CALBACK_0.getName()方法,当调用该方法时,Hibernate会首先检查CGLIB$CALBACK_0.target属性是否为null,如果不为空,则调用目标对象的getName方法,如果为空,则会发起数据库查询,生成类似这样的SQL语句:select * from parent where id=’1’;来查询数据,并构造目标对象,并且将它赋值到CGLIB$CALBACK_0.target属性中。
这样,通过一个中间代理对象,Hibernate实现了实体的延迟加载,只有当用户真正发起获得实体对象属性的动作时,才真正会发起数据库查询操作。
    <many-to-one> 的lazy设置为false时,抓取父对象没有采用代理机制。

4,用session.close(),执行多次查询后报session is closed的错误,而hibernateSessionFactory.closeSession()没有这个问题,这是什么原因?

5,ORA-01466: 无法读数据 - 表定义已更改
原因是系统时间修改造成的,其他原因详见
http://www.orafaq.com/usenet/comp.databases.oracle.server/2007/03/31/1586.htm

6,
spring的一个方法上有事务,先用hibernate加载一个对象,接着改变对象的某个属性的值,
再用sql去数据库查对应的记录,然后才提交。
用sql去查时发现对应的字段也改变了,这是怎么回事?


  

只有注册用户登录后才能发表评论。


网站导航: