mysql 别名 hibernate_MySQL使用列别名后Hibernate依然读原始列名而不是别名

现象

执行程序时报hibernate从返回结果集中找不到需要的字段,比如user_name

错误信息:

2020-05-15 10:37:01.330 [INFO][org.hibernate.type.StringType][nullSafeGet][180]-> could not read column value from result set: from_classifier_id; Column 'from_classifier_id' not found.

2020-05-15 10:37:01.332 [WARN][org.hibernate.util.JDBCExceptionReporter][logExceptions][77]-> SQL Error: 0, SQLState: S0022

2020-05-15 10:37:01.332 [ERROR][org.hibernate.util.JDBCExceptionReporter][logExceptions][78]-> Column 'from_classifier_id' not found.

[default][2020-05-15 10:37:01,334][ERROR][com.primeton.dgs.web.command.metamodel.PackageCommand][Line:442] 加载树失败

org.hibernate.exception.SQLGrammarException: could not execute query

at org.hibernate.exception.SQLStateConverter.convert(SQLStateConverter.java:67)

at org.hibernate.exception.JDBCExceptionHelper.convert(JDBCExceptionHelper.java:43)

at org.hibernate.loader.Loader.doList(Loader.java:2208)

at org.hibernate.loader.Loader.listIgnoreQueryCache(Loader.java:2102)

at org.hibernate.loader.Loader.list(Loader.java:2097)

问题排查过程

先看Hibernate的源码,最终找到了这么一段:

protected void autoDiscoverTypes(ResultSet rs) {

try {

//从结果集中提取元数据,其中就包含了列的元数据

Metadata metadata = new Metadata( getFactory(), rs );

List aliases = new ArrayList();

List types = new ArrayList();

rowProcessor.prepareForAutoDiscovery( metadata );

//循环从元数据中取并设置rowProcessor的列名(从结果集中取那些列的数据)

for ( int i = 0; i < rowProcessor.columnProcessors.length; i++ ) {

//在往里走就会去调用MySQL驱动中的代码,获取列名

rowProcessor.columnProcessors[i].performDiscovery( metadata, types, aliases );

}

resultTypes = ArrayHelper.toTypeArray( types );

transformerAliases = ArrayHelper.toStringArray( aliases );

}

catch ( SQLException e ) {

throw new HibernateException( "Exception while trying to autodiscover types.", e );

}

}

public void performDiscovery(Metadata metadata, List types, List aliases) throws SQLException {

if ( alias == null ) {

//根据位置从元数据中获取对应位置的列名,再去看MySQL源码就会发现本次问题的根本原因

alias = metadata.getColumnName( position );

}

else if ( position < 0 ) {

position = metadata.resolveColumnPosition( alias );

}

if ( type == null ) {

type = metadata.getHibernateType( position );

}

types.add( type );

aliases.add( alias );

}

再看MySQL驱动中的代码,最终定位到了Hibernate为什么会取到最初的列名,而不是别名

@Override

public String getColumnName(int column) throws SQLException {

if (this.useOldAliasBehavior) {

return getField(column).getName();

}

String name = getField(column).getOriginalName();

if (name == null) {

return getField(column).getName();

}

return name;

}

从代码中可以看到this.useOldAliasBehavior,说明在哪里是可以配置驱动到底返回原始列名还是别名,所以找度娘为了一下

解决

在jdbc.url中要增加一个参数,如下:

jdbc.url=jdbc:mysql://www.test.com:3306/test?useOldAliasMetadataBehavior=true

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值