场景
项目主体框架使用 spring4 以及 Hibernate4, 由于spring 升级到 5的大版本,附带的 Hibernate 也将被强迫升级
改动注意点
升级后主要改动点如下:
Hibernate 事务管理对象变更
若存在配置文件 applicationContext.xml
则修改如下:
原有为 hibernate4
Hibernate session Factor对象变更
若存在配置文件 applicationContext.xml
则修改如下:
原有为 hibernate4
<bean id="sessionFactory" class="org.springframework.orm.hibernate5.LocalSessionFactoryBean">
...............
</bean>
Jboss
若使用了 jboss
且出现
Caused by: java.lang.NoSuchMethodError: org.hibernate.internal.CoreMessageLogger.debugf(Ljava/lang/String;II)V
类似错误 请升级Jboss 到
<dependency>
<groupId>org.jboss.logging</groupId>
<artifactId>jboss-logging</artifactId>
<version>3.3.0.Final</version>
</dependency>
版本
hibernate.annotations.common
若出现:
Caused by: java.lang.NoSuchMethodError: org.hibernate.annotations.common.reflection.ReflectionManager.reset()
类似错误,那么
可以将
hibernate-commons-annotations
包去除,屏蔽错误(如果无实际使用)
若原有存在继承了 AliasedTupleSubsetResultTransformer 的类
AliasedTupleSubsetResultTransformer 改类来源于 Hibernate4 , 我原有使用的是 4.3.0.Final
切换 Hibernate5 后相关的部分类可能没有提供 如不需要可以去除该继承和相关实现。
实际上 sessionFactory 的创建方式若使用代码方式实现也会出现问题,但这里我没有遇到,从其他资料上看到也有相关的修改,这里如果有需要可以直接查询 Hibernate4 升级 Hibernate5 sessionFactory 的更改方式
Hibernate5 升级后的查询
实际上从 4 升级到 5 之后有相当一部分的方式都被弃用掉了
这里给出一些其他资料给出的参考资料:
在 Hibernate4 中,利用原生SQL语句查询时,
1、可使用Session.createSQLQuery(sql)建立Qurey(org.hibernate.Query),
2、可使用Query.setParameter(int index, Object obj),对sql语句中的参数根据位置进行参数值动态绑定;
升级到 Hibernate5 后
1、org.hibernate.Query 被标记为 @Deprecated
2、Session().createSQLQuery(sql) 返回类型为 org.hibernate.query.Query;
3、并且 Session().createSQLQuery 也已经被标记为 @Deprecated;
4、可使用 Session().createNativeQuery(sql) 代替 createSQLQuery。
5、createNativeQuery 返回的 Query, 不可 通过 setParameter(int index, Object obj) 根据位置 进行参数值动态绑定;只可以 通过 setParameter(String paramname, Object obj) 按参数名称绑定 。
6、createNativeQuery(sql)中的sql语句中的查询占位符只可使用 命名参数 方式进行编写。
升级到 Hibernate5 可能出现的问题
大量出现
Caused by: org.hibernate.exception.ConstraintViolationException: could not execute statement
Caused by: java.sql.SQLIntegrityConstraintViolationException: Duplicate entry ‘*’ for key ‘PRIMARY’
等,
可能的原因以及可以尝试的解决方式
ConstraintViolationException : 大概率和表设计中的约束相关,检查表设计中的 非空约束,外键约束,主键约束等等
Duplicate entry ‘*’ for key ‘PRIMARY’:
检查你的 @Entity 中使用的主键生成策略
@GeneratedValue(strategy = GenerationType.AUTO) 为在4中常用的策略 即 AUTO
在Hibernate 4和之前的版本中,使用GenerationType.AUTO意味着如果你连接的数据库支持 IDENTITY 或 AUTO_INCREMENT 数据类型,那么比使用基于表的序列更好。
对于Hibernate 5, GenerationType.AUTO将默认使用以前使用过 IDENTITY 或 AUTO_INCREMENT 数据库的基于表的序列。
可以通过一下一些方式尝试解决:
- 修改 生成 策略:更改所有 @GeneratedValue 注释,使用 GenerationType.IDENTITY 尝试是否可以恢复正常
- 或 修改 identifier mapping generators(标识符映射生成器) 的值为 true
- 更改java类以使用由 hibernate_sequences 表支持的命名序列生成器。 确定实体数据的 MAX(ID) ,并在hibernate_sequences表中为该实体的命名标识符设置适当的下一个id值。
这里可能麻烦的部分是你需要删除所有与这个实体的现有ID列相关的外键,改变它的数据类型,使它不是 AUTO_INCREMENT 或IDENTITY ,而是像 BIGINT 或 INT 。 然后你把外键约束放回去。