Spring Data JPA原生查询报No Dialect mapping for JDBC type: -155如何解决
错误原因
JDBC类型码-155对应TIMESTAMP_WITH_TIMEZONE类型,你使用的Hibernate数据库方言默认没有注册该类型到Java Instant的映射规则。原生查询场景下Spring Data JPA的接口投影不会自动处理该类非标SQL类型的转换,所以触发映射错误。
sum生成的numeric(12,2)类型部分方言映射到Double也可能存在兼容问题,属于次要诱因。
修复方案
- 方案1:自定义方言注册映射规则
以PostgreSQL为例,继承官方方言类新增类型注册,代码如下:
在配置文件中替换默认方言配置:import org.hibernate.dialect.PostgreSQLDialect; import java.sql.Types; import org.hibernate.type.StandardTypes; public class CustomPostgresDialect extends PostgreSQLDialect { public CustomPostgresDialect() { super(); // 注册TIMESTAMP_WITH_TIMEZONE到Instant的映射 registerHibernateType(Types.TIMESTAMP_WITH_TIMEZONE, StandardTypes.INSTANT.getName()); // 可选:注册numeric到Double的映射避免saving字段报错 registerHibernateType(Types.NUMERIC, StandardTypes.DOUBLE.getName()); } }spring.jpa.properties.hibernate.dialect=com.yourpackage.CustomPostgresDialect - 方案2:SQL层面转换类型
修改原生查询语句,将带时区的时间戳转为普通timestamp,sum结果转为double类型:
该方案无需修改代码配置,兼容性更好。select ti.id, cast(ti.timestamp as timestamp) as timestamp, ti.fuel_station_id, ti.cash_register_id, cast(sum(cast(dsc.discount as numeric(12,2))) as double precision) as saving from transaction_info as ti join discount dsc on ti.id = dsc.transaction_id where ti.user_id = :userId and ti.timestamp >= :timeFrom - 方案3:调整投影接口类型
可选将Saving接口中的getTimestamp()返回值改为LocalDateTime,getSaving()返回值改为BigDecimal,避开未注册的类型映射。
内容的提问来源于stack exchange,提问作者Martin Edlman
相关产品推荐
相关产品推荐

