原来的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
*/
@Override
protected 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
是推荐用于二进制数据的字段类型。