Apache Ignite(2.13.0)+Spring Boot更新语句异常问题求助
Ignite跨操作类型更新Timestamp列触发BinaryObjectException问题解决
问题现象
- 异常触发场景:通过Ignite Repository插入数据后,使用原生SQL查询更新包含timestamp类型的列时,抛出如下异常:
class org.apache.ignite.binary.BinaryObjectException: Invalid flag value: 32 at org.apache.ignite.internal.binary.builder.BinaryBuilderReader.parseValue(BinaryBuilderReader.java:863) at org.apache.ignite.internal.binary.builder.BinaryObjectBuilderImpl.serializeTo(BinaryObjectBuilderImpl.java:290) at org.apache.ignite.internal.binary.builder.BinaryBuilderSerializer.writeValue(BinaryBuilderSerializer.java:103) at org.apache.ignite.internal.binary.builder.BinaryBuilderSerializer.writeValue(BinaryBuilderSerializer.java:56) at org.apache.ignite.internal.binary.builder.BinaryObjectBuilderImpl.serializeTo(BinaryObjectBuilderImpl.java:297) at org.apache.ignite.internal.binary.builder.BinaryBuilderSerializer.writeValue(BinaryBuilderSerializer.java:103) at org.apache.ignite.internal.binary.builder.BinaryBuilderSerializer.writeValue(BinaryBuilderSerializer.java:56) at org.apache.ignite.internal.binary.builder.BinaryObjectBuilderImpl.serializeTo(BinaryObjectBuilderImpl.java:297)
- 正常场景:统一使用Ignite Repository执行所有增删改操作,或统一使用原生SQL执行所有增删改操作,均无异常。
问题原因
Ignite Repository基于Binary Object序列化机制存储数据,而原生SQL使用SQL类型的序列化逻辑,二者对timestamp字段的存储格式存在差异。当用Repository插入的数据被原生SQL更新时,SQL解析器无法识别Binary Object格式的timestamp字段,从而触发格式不兼容的异常。
解决方案
统一操作方式
保持所有数据操作(插入、更新、查询)使用同一种方式:要么全用Ignite Repository,要么全用原生SQL,从根源避免两种序列化格式的冲突。显式指定字段SQL类型
在实体类的timestamp字段上添加@QuerySqlField注解并明确指定SQL类型,强制Binary Object和SQL操作使用一致的字段解析规则:
import org.apache.ignite.cache.query.annotations.QuerySqlField; import java.sql.Timestamp; public class YourEntity { // 其他字段... @QuerySqlField(type = QuerySqlField.Type.TIMESTAMP) private Timestamp createTime; // getter/setter... }
- 调整Binary序列化配置
修改Ignite配置,禁用紧凑页脚以增强Binary Object与SQL类型的兼容性:
import org.apache.ignite.configuration.IgniteConfiguration; import org.apache.ignite.configuration.BinaryConfiguration; IgniteConfiguration igniteCfg = new IgniteConfiguration(); BinaryConfiguration binaryCfg = new BinaryConfiguration(); binaryCfg.setCompactFooter(false); igniteCfg.setBinaryConfiguration(binaryCfg); // 启动Ignite Ignite ignite = Ignition.start(igniteCfg);
- 临时兼容方案(Workaround)
如果无法统一操作方式,可在原生SQL更新时显式转换字段类型,比如使用CAST函数:
UPDATE your_table SET create_time = CAST(? AS TIMESTAMP) WHERE id = ?
内容的提问来源于stack exchange,提问作者Muhammad Osama Khan
相关产品推荐
相关产品推荐

