Hibernate版本升级bug解决全过程

文章讲述了作者在将Hibernate从5.x升级到6.x时,遇到查询时的错误,发现新版本中Hibernate倾向于使用实体类属性名称作为SQL列名,导致与旧版不同,解决方法是调整SQL语句的列名与实体类属性一致。
摘要由CSDN通过智能技术生成

背景:最近在升级hibernate的版本,由hibernate5.x升级至hibernate6.x,记录下在查询数据时遇到的问题。

1.执行如下代码:

2.报错现象:

org.hibernate.query.sqm.InterpretationException: Error interpreting query [from IntentModel a where id=1 order by a.create_time ]; this may indicate a semantic (user query) problem or a bug in the parser [from IntentModel a where id=1 order by a.create_time ]

3.问题分析:

(1)根据错误信息可以确定表【IntentModel】是真实存在的,查看表结构,确实存在id和create_time列,所以可以明确不是表结构的问题。

(2)回看代码,就是一个根据条件查询数据的SQL,查询条件有两个,拆开一个一个执行,发现问题问题出现order by a.create_time语句上。

(3)由(2)中的结论得知create_time也是存在的,所以怀疑是不是实体类上的@Column(name = "create_time")是不是没生效,但很快又被我推翻了,如果注解没生效,那么表结构中应该没有create_time列,陷入了沉思~~~~

(4)拆开查询条件执行时,发现id列作为查询条件时都可以执行成功,create_time列作为查询条件确抛异常,所以很明确就是create_time的问题,我又试了试其他的列作为查询条件是否能成功,惊喜马上就要出现了,发现SQL中的列名和实体类属性名称一模一样的就可以成功,反之不一样的就会抛异常,大胆怀疑就是SQL中写的列名和数据库中的列名映射出了问题,可明明都是create_time,为啥会这样呀,于是我将SQL中的列名改成了属性名createTime【不是@Column(name = "create_time")中的name】,查询成功。

(5)问题解决后,我查询了相关资料后,发现hibernate5.x升级到hibernate6.x版本之后,SQL语句也发生了变化。

4.总结如下:

Hibernate 5.x版本中,使用@Column注解时,Hibernate会使用@Column注解的name属性作为列名来创建SQL查询。而在Hibernate 6.x版本中,Hibernate更倾向于使用实体类的属性名称作为SQL查询的列名。

这种变化可能是为了提高Hibernate与实体类之间的映射一致性,以及提高代码的可读性。Hibernate 6.x版本更加强调与JPA规范的一致性,因此在处理列名时,它更倾向于使用实体类的属性名称。

扩展

Hibernate 6.x对命名策略的调整:在Hibernate 6.x中,命名策略(naming strategy)的实现和应用有所调整。尽管你可能在实体类的属性上使用@Column(name = "column_name")来指定数据库列名,但Hibernate在构建HQL或原生SQL查询时,会根据配置的命名策略来转换实体属性名。默认情况下,Hibernate会将实体类中的Java命名风格(驼峰命名法)转换为数据库风格(下划线分隔的小写命名)。

HQL与SQL查询的差异:在使用HQL(Hibernate Query Language)查询时,你通常会直接引用实体类属性名,而Hibernate会自动处理属性名与数据库列名之间的映射关系。但在使用原生SQL查询时,你直接在查询语句中引用数据库列名,因此需要使用数据库中的实际列名,这可能与实体类属性名不一致。

在HQL(Hibernate Query Language)查询中,直接使用实体类的属性名是标准做法,因为Hibernate会根据配置的命名策略自动处理属性名到数据库列名的映射。这意味着在HQL中使用firstName而不是first_name是推荐的,因为Hibernate会自动将驼峰命名的Java属性名转换为数据库中相应的下划线分隔的小写列名。如果Hibernate的命名策略被配置为将firstName转换为first_name,直接使用first_name可能与命名策略的自动转换逻辑冲突,导致Hibernate无法正确解析查询。

使用SQL查询:如果你的查询需求无法通过HQL表达,或者你确实需要直接操作数据库列名,可以考虑使用原生SQL查询。在Hibernate中,你可以通过createSQLQuery方法来执行原生SQL查询,这样就可以直接使用first_name数据库列名。

3.6.10.Final 2012-02-09 3.6.9.Final 2011-12-15 3.6.8.Final 2011-10-27 3.6.7.Final 2011-08-17 3.6.6.Final 2011-07-21 3.6.5.Final 2011-06-09 3.6.4.Final 2011-05-05 3.6.3.Final 2011-04-06 3.6.2.Final 2011-03-10 3.6.1.Final 2011-02-03 3.6.0.Final 2010-10-14 3.6.0.CR2 2010-09-29 3.6.0.CR1 2010-09-16 3.5.6-Final 2010-09-15 3.6.0.Beta4 2010-09-02 3.5.5-Final 2010-08-18 3.6.0.Beta3 2010-08-18 3.6.0.Beta2 2010-08-04 3.5.4-Final 2010-07-22 3.6.0.Beta1 2010-07-21 3.5.3-Final 2010-06-17 3.5.2-Final 2010-05-14 3.5.1-Final 2010-04-15 3.5.0-Final 2010-03-31 3.5.0-CR-2 2010-02-25 3.5.0-CR-1 2010-02-10 3.5.0-Beta-4 2010-01-29 3.5.0-Beta-3 2010-01-14 3.5.0-Beta-2 2009-11-03 3.5.0.Beta-1 2009-08-21 3.3.2.GA 2009-06-24 3.2.7.ga 2009-06-03 3.3.1.GA 2008-09-11 3.3.0.SP1 2008-08-20 3.3.0.GA 2008-08-15 3.3.0.cr2 2008-08-01 3.3.0.cr1 2008-04-29 3.2.6.ga 2008-02-07 3.2.5.ga 2007-07-31 3.2.4.sp1 2007-05-18 3.2.4.ga 2007-05-09 3.2.3.ga 2007-04-02 3.2.2.ga 2007-01-24 3.2.1.ga 2006-11-17 3.2.0.ga 2006-10-16 3.2.0.cr5 2006-10-05 3.2.0.cr4 2006-08-25 3.2.0.cr3 2006-07-06 3.2 cr2 2006-05-06 3.2 cr1 2006-03-27 3.1.3 2006-03-20 3.2 alpha2 2006-03-16 3.2 alpha1 2006-03-01 3.1.2 2006-01-28 3.1.1 2006-01-18 3.1 2005-12-12 3.1 rc1 2005-12-12 3.1 rc3 2005-11-18 3.1 rc2 2005-10-17 3.1 beta 3 2005-09-13 3.1 beta2 2005-08-16 3.1 beta1 2005-07-21 3.1 alpha1 2005-06-24 3.0.5 2005-05-25 3.0.4 2005-05-23 3.0.3 2005-05-08 3.0.2 2005-04-27 3.0.1 2005-04-18 3.0 final 2005-03-31 3.0 rc 1 2005-02-28 3.0 beta 4 2005-02-11 3.0 beta 3 2005-01-30 3.0 beta 2 2005-01-24 3.0 beta 1 2004-12-20 3.0 alpha 2004-08-23
Hibernate是一个开源的对象关系映射(ORM)框架,用于将Java应用程序中的对象与数据库表关联起来。查看Hibernate版本号的方法取决于你是在项目中查看还是通过网络或文件来确定。 如果你已经在项目中使用了Hibernate,可以通过以下步骤来查看版本号: 1. 在项目中找到包含Hibernate依赖的`pom.xml`文件(如果是Maven项目)或`build.gradle`文件(如果是Gradle项目)。 2. 查看相应的依赖项,通常会包含版本信息,例如: - Maven项目中可能包含类似这样的依赖:`<artifactId>hibernate-core</artifactId><version>5.4.1.Final</version>` - Gradle项目中可能包含类似这样的依赖:`implementation 'org.hibernate:hibernate-core:5.4.1.Final'` 3. 如果你是通过IDE(如IntelliJ IDEA或Eclipse)查看项目,通常可以在项目的依赖管理界面中找到Hibernate及其版本号。 如果需要查看正在运行的应用程序中Hibernate的版本号,可以通过以下方式: 1. 使用Java反射机制来获取Hibernate版本信息。可以编写一个简单的Java类或使用JShell来执行以下代码片段: ```java import org.hibernate.Version; public class HibernateVersion { public static void main(String[] args) { System.out.println(Version.getVersionString()); } } ``` 执行该代码会打印出Hibernate的版本号。 2. 如果你无法直接访问源代码或运行时环境,你可能需要查看项目的文档或联系项目负责人来获取Hibernate的版本号。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值