You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spring Boot+Spark 3.2.1调用Dataset.show()方法报错求助

问题分析与解决方案

问题描述

使用Spring Boot + Apache Spark 3.2.1通过JDBC读取Hive数据时,调用Dataset.show()方法抛出以下错误:

org.apache.spark.scheduler.DAGScheduler : ResultStage 7 (show at SampleHiveController.java:62) failed in 7,461 s due to Job aborted due to stage failure: Task 0 in stage 7.0 failed 1 times, most recent failure: Lost task 0.0 in stage 7.0 (TID 5) : java.sql.SQLException: Illegal conversion at org.apache.hive.jdbc.HiveBaseResultSet.getBigDecimal(HiveBaseResultSet.java:137)

调用count()和printSchema()方法均正常运行,相关代码如下:

@RequestMapping(value = "/spark", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity<List<Map<String, Object>>> showSpark() {
    SparkSession spark = SparkSession
        .builder()
        .master("local")
        .appName("Java Spark Hive Example")
        .enableHiveSupport()
        .getOrCreate();

    Dataset<Row> df = spark.read()
        .format("jdbc")
        .option("url", "jdbc:hive2://hdp31-dev-03.dmp.test.com:2181,hdp31-dev-01.dmp.test.com:2181,hdp31-dev-02.dmp.test.com:2181/;serviceDiscoveryMode=zooKeeper;zooKeeperNamespace=hiveserver2;principal=hive/_HOST@WE.TEST.COM")
        .option("dbtable", "dds_test.test")
        .option("user", "user")
        .option("password", "test")
        .option("driver", "org.apache.hive.jdbc.HiveDriver")
        .load();
    System.out.println("*** Right after ingestion");

    df.printSchema();
    df.show();
}

原因分析

show()方法需要完整序列化并展示数据,而count()仅统计行数、printSchema()仅读取元数据,都不会触发全量数据类型转换。报错指向getBigDecimal的非法转换,说明Hive表中存在Spark JDBC驱动无法自动转换为BigDecimal的字段类型——比如Hive的decimal精度/标度超出驱动支持范围、字段存储了非数值内容,或是Spark与Hive的类型映射规则不兼容。

解决方案

方案1:指定自定义字段映射

在JDBC读取时,通过customSchema参数强制指定字段类型,绕过自动转换逻辑:

Dataset<Row> df = spark.read()
    .format("jdbc")
    .option("url", "...")
    .option("dbtable", "dds_test.test")
    .option("user", "user")
    .option("password", "test")
    .option("driver", "org.apache.hive.jdbc.HiveDriver")
    // 将问题字段转为String,后续按需处理
    .option("customSchema", "id INT, problematic_col STRING, other_col DOUBLE")
    .load();

方案2:调整Spark类型转换配置

修改Spark的JDBC转换规则,允许宽松转换或精度损失:

spark.conf().set("spark.sql.decimalOperations.allowPrecisionLoss", "true");
spark.conf().set("spark.sql.jdbc.typeConversionMode", "relaxed");

添加上述配置后再读取数据,可避免严格类型校验导致的报错。

方案3:使用Hive原生读取

既然已启用enableHiveSupport(),直接通过Spark SQL读取Hive表,跳过JDBC层的类型转换问题:

Dataset<Row> df = spark.sql("SELECT * FROM dds_test.test");

需确保Spark配置了正确的Hive metastore地址,保证元数据同步。

方案4:检查并修复Hive表

查看Hive表结构和数据,定位异常字段:

-- 查看表结构
DESCRIBE dds_test.test;
-- 检查问题字段数据
SELECT problematic_col FROM dds_test.test LIMIT 10;

若存在decimal类型精度超标或数据非法,可修改表结构或清洗数据。

内容的提问来源于stack exchange,提问作者Tim

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.30 03:24:57