HIBERNATE 的乐观锁@VERSION和 MYSQL 的两个小问题
2015-12-24 13:56
513 查看
MySQL的设计者一直没有支持精度到毫秒或者纳秒的Timestamp类型,过去一直只能支持到秒。这虽然不太方便但是也凑合着能用,比如我通过程序代码插入long int也可以。但是Hibernate的实体如果用了@Version在MySQL一个时间字段上做乐观锁,就有问题了。Hibernate比较实体对象是否改变过,是根据@version字段的值,由于MySQL的DATETIME类型不能包含毫秒,纳秒,所以比较的时候会有问题,导致Hibernate认为实体Version不相等,抛HibernateOptimisticLockingFailureException给你。
MySQL 6 才会支持毫秒,所以目前你只能用INT或者BIGINT来保存Version了。
但是就算是你用了INT你可能仍然遇到别的错误
Caused by: java.lang.NullPointerException
at org.hibernate.type.IntegerType.next(IntegerType.java:59)
at org.hibernate.engine.Versioning.increment(Versioning.java:108)
at org.hibernate.event.def.DefaultFlushEntityEventListener.getNextVersion(DefaultFlushEntityEventListener.java:365)
at org.hibernate.event.def.DefaultFlushEntityEventListener.scheduleUpdate(DefaultFlushEntityEventListener.java:257)
at org.hibernate.event.def.DefaultFlushEntityEventListener.onFlushEntity(DefaultFlushEntityEventListener.java:128)
这个错误一看就头大了吧,Hibernate的源代码是这样的
public Object next(Object current, SessionImplementor session) {
return new Integer( ( (Integer) current ).intValue() + 1 );
}
初步分析原因是前面事件通知的时候传入的当前version是空的,具体看这里 http://opensource.atlassian.com/projects/hibernate/browse/HHH-3030
最简单的解决办法是给@version字段在数据库里设置一个默认值,比如0
Opensource意味着你不能发现bug的时候打电话对售后大喊大叫,没办法,要么自己写一个hotfix,要么等官方fix吧。
MySQL 6 才会支持毫秒,所以目前你只能用INT或者BIGINT来保存Version了。
但是就算是你用了INT你可能仍然遇到别的错误
Caused by: java.lang.NullPointerException
at org.hibernate.type.IntegerType.next(IntegerType.java:59)
at org.hibernate.engine.Versioning.increment(Versioning.java:108)
at org.hibernate.event.def.DefaultFlushEntityEventListener.getNextVersion(DefaultFlushEntityEventListener.java:365)
at org.hibernate.event.def.DefaultFlushEntityEventListener.scheduleUpdate(DefaultFlushEntityEventListener.java:257)
at org.hibernate.event.def.DefaultFlushEntityEventListener.onFlushEntity(DefaultFlushEntityEventListener.java:128)
这个错误一看就头大了吧,Hibernate的源代码是这样的
public Object next(Object current, SessionImplementor session) {
return new Integer( ( (Integer) current ).intValue() + 1 );
}
初步分析原因是前面事件通知的时候传入的当前version是空的,具体看这里 http://opensource.atlassian.com/projects/hibernate/browse/HHH-3030
最简单的解决办法是给@version字段在数据库里设置一个默认值,比如0
Opensource意味着你不能发现bug的时候打电话对售后大喊大叫,没办法,要么自己写一个hotfix,要么等官方fix吧。
相关文章推荐
- Hibernate与Mysql 5.5创建表出错--table doesn't exist
- 一百万数据索引实例測试--mysql
- Mysql SQL random read n item data from a table ( Mysql随机读取SQL查询语句 )
- mysql中int(10)和char(10)以及varchar(10)的区别
- ImportError: No module named MySQLdb 解决方案
- mysql 存储过程
- MySql5.0安装步骤
- MySQL中同一时候存在创建和上次更新时间戳字段解决方法浅析
- MySQL数据库大小写敏感问题
- MySQL子查询
- Mysql随机插入数字、日期、时间戳
- Host 'XXX' is not allowed to connect to this MySQL server 解决方案/如何开启MySQL的远程帐号
- 重启mysql的命令
- mysql case when
- 写MySQL存储过程实现动态执行SQL
- MySql日期函数(二)
- mysql升级5.7失败,报错[Err] 1146 - Table 'performance_schema.session_status' doesn't exist
- mysql 获取当前日期及格式化(一)
- mysql处理字符串的两个绝招:substring_index,concat最近老是碰到要处理数据
- mysql存储过程按月创建表分区 方式二