您的位置:首页 > 其它

Hibernate保存记录时遇到的一个问题----evitic,not-null配置及主键生成策略

2011-07-20 15:45 417 查看
项目中遇到的几个问题,总结一下,都是与hibernate相关的:我要为某一个表(如UserInfo表)保存一条新数据,结果遇到如下的问题
1)UserInfo urf = new UserInfo();
urf.setUserCde("zhangsan_001"); -----此列为主键
urf.setUserName("张三");
urf.setUserAge(22);
urf.setUserSex("男");
session.save(urf); -------1
session.evitic(urf); -------2

结果在运行的时候,报错:possible nonthreadsafe access to session
在查找相关资料的后,通过在1和2之间加入session.flush();方法解决。

参考资料:http://joes0619.blog.163.com/blog/static/1042350320069305011256/
总的来说,就是在使用flush();方法后,数据会同步更新到数据库中。但是这样的更新是按照一定的次序进行的,insert....update....delete的顺序进行的。

而产生这个错误的原因,是因为,urf对象过早的从session中拆离出来。导致在后面hibernate与数据库同步的时候,找不到与session关联的对象。就像上面链接中提到的hiberante的执行过程所提到的那样:“Hibernate在数据库层之上实现了一个缓存区,当应用save或者update一个对象时,Hibernate并未将这个对象实际的写入数据库中,而仅仅是在缓存中根据应用的行为做了登记,在真正需要将缓存中的数据flush入数据库时才执行先前登记的所有行为。”
2)在了解了hibernate的flush机制之前,还曾经因为在UserInfo.hbm.xml的配置中的Age属性有的一个not-null配置,导致我在未给Age赋值时出现错误。
具体的配置为如下:
<property name="Age" type="java.lang.Integer">
<column name="AGE" length="1" not-null="true" />
</property>
注意,以上属性是hibernate在配置文件中进行的非空约束,而在实际的数据库表中则没有此约束。如果通过hibernate来对数据进行数据的操作,则受此约束影响。
3)在解决如上两个问题后,终于成功插入了一条数据。嗯,那就去数据库里面查一下是不是有这条数据吧。结果,我发现,数据库中存的主键字段UserCde的值为“202011072000001”(此处为举例,类似的一串随机数或流水号)。
我实在是很费解,我明明设置的urf的UserCde为“zhangsan_001”,实际到数据库的为什么变了呢?纠结之后,我就去找UserInfo的hibernate配置文件,在看到主键配置的那一刻,我终于明白了。配置如下:
<id name="UserCde" type="java.lang.String">
<column name="USERCDE" length="50" />
<generator class="uuid.hex"></generator>
</id>
这里的主键生成策略,竟然为自动生成的一串随机数。解决这个问题,要么把这个配置去掉,要么直接写sql语句,绕过hibernate的配置文件。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: