原来的quartz部分表字段为blob,但是迁移到gaussDB下的时候,不兼容,故修改为BYTEA,但是定时任务运行的时候报错:java.lang.NumberFormatException: For input string: "\x",说明是反序列化出了问题。
简单翻了下源码,也没有细看,决定直接修改其中的反序列blob字段部分的代码;
/*** description:* gaussDB下反序列blob字段报错:java.lang.NumberFormatException: For input string: "\x"** @author Vic.xu* @since 2024-10-31 14:42*/public class CustomGaussDBDelegate extends StdJDBCDelegate {/*** 重写获取逻辑,直接rs.getBytes 而不是 rs.getBlob*/@Overrideprotected Object getObjectFromBlob(ResultSet rs, String colName)throws ClassNotFoundException, IOException, SQLException {Object obj = null;byte[] bytes = rs.getBytes(colName);if (bytes != null && bytes.length > 0) {try (ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(bytes);ObjectInputStream objectInputStream = new ObjectInputStream(byteArrayInputStream)) {obj = objectInputStream.readObject();} catch (Exception e) {return super.getObjectFromBlob(rs, colName);}}return obj;}}
StdJDBCDelegate 原本的代码如下:
public class StdJDBCDelegate implements DriverDelegate, StdJDBCConstants { // 反序列化为对象protected Object getObjectFromBlob(ResultSet rs, String colName)throws ClassNotFoundException, IOException, SQLException {Object obj = null;Blob blobLocator = rs.getBlob(colName);if (blobLocator != null && blobLocator.length() != 0) {InputStream binaryInput = blobLocator.getBinaryStream();if (null != binaryInput) {if (binaryInput instanceof ByteArrayInputStream&& ((ByteArrayInputStream) binaryInput).available() == 0 ) {//do nothing} else {ObjectInputStream in = new ObjectInputStream(binaryInput);try {obj = in.readObject();} finally {in.close();}}}}return obj;}//序列化为二进制protected void setBytes(PreparedStatement ps, int index, ByteArrayOutputStream baos) throws SQLException {ps.setBytes(index, (baos == null) ? new byte[0] : baos.toByteArray());}}
入库时候的序列化没有动,只是修改了获取数据库字段的代码:
rs.getBytes 修改为 rs.getBlob
<!-使用自定义delegate,兼容gaussDB-><prop key="org.quartz.jobStore.driverDelegateClass">cn.xuqiudong.extension.quartz.CustomGaussDBDelegate</prop>
根源还是出在gaussdb上:在 GaussDB 中,BYTEA 是推荐用于二进制数据的字段类型。