clickhouse-java icon indicating copy to clipboard operation
clickhouse-java copied to clipboard

jdbc版本升级到0.4.2之后,出现UnsignedLong cannot cast to long的报错

Open Lqinhao opened this issue 2 years ago • 13 comments

SQL查询结果使用Map作为resultMap,count函数使用Java中Long类型接收对应的value,SQL查询报错:clickhouse.value.UnsignedLong cannot cast to Long

Lqinhao avatar Aug 16 '23 02:08 Lqinhao

Hi @Lqinhao, have you tried 0.4.6? Besides, could you provide sample code to reproduce the issue as well as stack trace of the error?

zhicwu avatar Aug 16 '23 04:08 zhicwu

0.4.6也是一样的报错。我的工程是springboot + mybatis + clickhouse,通过mybatis封装SQL。代码样例: <select id="queryCount" resultMap = "java.util.Map"> select count(*), countIf(id=1) from table

Lqinhao avatar Aug 16 '23 06:08 Lqinhao

clickhouse.value.UnsignedLong这个类在0.4.1版本还不存在,我将jdbc的版本切换到0.4.1的时候找不到对应的导包。0.4.2才有了这个类

Lqinhao avatar Aug 16 '23 06:08 Lqinhao

Could you post stack trace? The change was added in #1124 to ensure the Java lib can handle large numbers correctly.

If you don't want to use ResultHandler, you may try two workarounds: 1) explicitly specifying type java.lang.Long for UInt64 columns in mybatis, which could be tedious to do; 2) set typeMappings to UInt64=java.lang.Long in connection properties to use Java long instead of the default com.clickhouse.value.UnsignedLong.

zhicwu avatar Aug 16 '23 07:08 zhicwu

因为我查询的结果是两个值,所以我使用了Map作为resultMap接收mybatis查询的结果,查询到结果在代码中就直接get对应的value,所以具体的堆栈打印就只有一句ClassCastException:com.clickhouse.data.value.UnsignedLong cannot be cast to java.lang.Long。debug中可以看到Map接收到的结果中value对应的类型已经变为UnsignedLong了,你们这种改变是完全出乎我们使用的习惯的

Lqinhao avatar Aug 16 '23 09:08 Lqinhao

"The change was added in https://github.com/ClickHouse/clickhouse-java/pull/1124 to ensure the Java lib can handle large”numbers correctly." 这个改变只是clickhouse中的数据类型与Java中数据类型的映射,但是我出错的是count函数而不是单个字段

Lqinhao avatar Aug 16 '23 09:08 Lqinhao

你们这种改变是完全出乎我们使用的习惯的

Apologies for any inconvenience, but ensuring the accuracy of the value is crucial. It's important to note that Java's long data type cannot accurately represent UInt64. As I understand it, MyBatis employs ResultSet.getObject() rather than getLong() or getBigDecimal() to fetch the value, although this behavior could be altered. Have you considered testing the second workaround?

但是我出错的是count函数而不是单个字段

By default, the return type of the count* function is UInt64.

zhicwu avatar Aug 16 '23 11:08 zhicwu

第二种方法我试过了是可以解决我出现的问题的,感谢

Lqinhao avatar Aug 17 '23 06:08 Lqinhao

Thank you for confirming the workaround. I'd like to emphasize that Java's long data type cannot accurately represent UInt64. Consequently, if you don't want to use UnsignedLong provided by this lib, you may want to consider using BigInteger or BigDecimal for accurate representation.

I'm not familiar with MyBatis, but it's possible that we require a dialect or a similar component in this driver to enhance its compatibility with the existing persistence framework.

zhicwu avatar Aug 17 '23 23:08 zhicwu

我现在又发现新的报错UnsignedInteger can not cast to long,我如果想将UnsignedLong和UnsignedInteger同时映射给long,应该怎么修改?

Lqinhao avatar Sep 20 '23 03:09 Lqinhao

It's comma separated key-value pairs, so you may try UInt64=java.lang.Long,UInt32=java.lang.Long or UInt64=java.math.BigInteger,UInt32=java.lang.Long.

zhicwu avatar Sep 20 '23 23:09 zhicwu

我又发现了另一个问题,我在升级版本之前,clickhouse表中有一列属性为Float32 default 0,在插入null值时是OK的,但是在新的版本这个操作会直接报错

Lqinhao avatar Oct 07 '23 10:10 Lqinhao

第二种方法我试过了是可以解决我出现的问题的,感谢

请问咋解决的呀

StoneForests avatar Mar 29 '24 01:03 StoneForests