明明是updateTime却报:org.h2.jdbc.JdbcSQLSyntaxErrorException: Column "update_time" not found

背景

使用“Spring Boot With H2 Database”+“Spring Data JPA”写的一个小东西,第一次用下h2和jpa,有几个小问题,挑一个记录下。

问题说明

1. 定义一个实体类,其中有一个更新时间属性,定义如下:

2. 在数据库表中定义这个字段:

3. 查询sql:

4. 执行报错:

其实,我整个代码与sql脚本都没有update_time字段,初用jpa,也没仔细了解有什么规范,我当时猜测,可能是我的代码少了什么映射配置,或者是框架层面自己给我转换了。

分析

我看了下异常栈最近的有用的方法调用信息:

在源码这里:

这个columnLabel变量的值是update_time。

这里出现问题的基本原因是,执行sql拿到结果集,期望从结果集取update_time列的过程中出问题了。问题是在columnLabelMap这里,debug看了下这个变量的信息,根据经验猜测应该是框架初始化过程中,对实体类相关字段作映射解析的时候转换的时候发生的。

以前没怎么用过hibernate,比较好奇这个转换的过程,所以小小研究了下,

于是根据调用栈从下往上翻了一下源码及debug,花了几十分钟,终于找到了这个解析转换的源码位置:

先看下这代码入口:在AnnotationBinder.java的bindClass方法上,关注点在persistenClass变量上,这里将要处理为类就是我定义的这个实体类

中间过程这里不多说,接下来要处理实体类字段注解,会走到这里:在AnnotationBinder.java类里,会解析字段上的各种注解,

按我的配置是要走到这里:Ejb3Column.java里这个方法处

前面解析注解的时候,不论@Column注解是否存在并且定义的name是不是空,只要进入redefineColumnName方法,都会调用这段代码:

如果没有使用@Column注解指定,就是else上面使用的那个隐式命名:implicitName,都没有区别,重要是这个命名策略的转换过程,这个physicalNamingStrategy,这里默认的是SpringPhysicalNamingStrategy,看下这个实现,我加上了注释:

	@Override
	public Identifier toPhysicalColumnName(Identifier name,
			JdbcEnvironment jdbcEnvironment) {
		return apply(name, jdbcEnvironment);
	}

	private Identifier apply(Identifier name, JdbcEnvironment jdbcEnvironment) {
		if (name == null) {
			return null;
		}
		StringBuilder builder = new StringBuilder(name.getText().replace('.', '_'));
		for (int i = 1; i < builder.length() - 1; i++) {
            // 如果前一个字母是小写,当前字母是大写,后一个字母是小写(驼峰命名)
            // 就在这个位置插入一个下划线
			if (isUnderscoreRequired(builder.charAt(i - 1), builder.charAt(i),
					builder.charAt(i + 1))) {
				builder.insert(i++, '_');
			}
		}
        // 转换小写返回
		return getIdentifier(builder.toString(), name.isQuoted(), jdbcEnvironment);
	}

这就是转换的地方,其实问题不大。

解决办法

我简单浏览下源码包下的所有注解,发现好像没看到哪个注解能达到我想要的效果。

必须承认我对这套东西用的少,不怎么了解,感觉还是Mybatis以sql为中心用着舒服,可能用惯了。

大致明白解析过程,其实有好几个地方可以绕过去,比如查询sql取个巧:

或者命名上不规范点,最终我觉得还是正常点,数据表定义规范点,这个字段改一下,改成update_time好了,图省事。

后续有时间再翻下资料,了解下规范,找个正常点通用的方案。

 

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

不识君的荒漠

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值