Posted on 2007-09-28 03:51
leekiang 阅读(633)
评论(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去查时发现对应的字段也改变了,这是怎么回事?