Ik heb het probleem opgelost dankzij het antwoord van @gvenzi, maar besloot mijn eigen antwoord te posten omdat ik wat aanvullende opmerkingen heb.
Dus ja, OracleLobHandler
lost het probleem op. Maar in feite zijn we niet gedwongen om verouderde klassen te gebruiken. In de OracleLobHandler documentatie
Ik vond
Ik heb het getest en het werkt.
Maar ik had een ander probleem met het gebruik van SqlLobValue
samen met OracleTypes.BLOB
in PreparedStatementSetter
(het wordt hier beschreven ClassCastException:SqlLobValue kan niet worden gecast naar oracle.sql.BLOB met behulp van PreparedStatementSetter
)
Mijn definitieve werkende code is als volgt:
public void saveThumbnails(List<Thumbnail> fileList) throws SQLException, IOException {
BatchPreparedStatementSetter b = new BatchPreparedStatementSetter() {
@Override
public void setValues(PreparedStatement ps, int i) throws SQLException {
Thumbnail thumbnail = fileList.get(i);
byte[] thumbnailBytes = thumbnail.getThumbnail();
ps.setObject(1, thumbnail.getFileCId(), OracleTypes.NUMBER);
ps.setObject(2, thumbnail.getType().toString(), OracleTypes.VARCHAR);
DefaultLobHandler lobHandler = new DefaultLobHandler();
lobHandler.setCreateTemporaryLob(true);
lobHandler.getLobCreator().setBlobAsBytes(ps, 3, thumbnailBytes);
}
@Override
public int getBatchSize() {
return fileList.size();
}
};
jdbcTemplate.batchUpdate(getSaveThumbnailSql(), b);
}
private String getSaveThumbnailSql() {
// @formatter:off
String sql = ""
+ "MERGE INTO file_thumbnails "
+ " USING (SELECT ? as file_c_id, ? as thumbnail_type, ? AS thumbnail_image FROM DUAL) tmp "
+ " ON (file_thumbnails.file_c_id = tmp.file_c_id AND "
+ " file_thumbnails.thumbnail_type = tmp.thumbnail_type) "
+ " WHEN MATCHED THEN "
+ " UPDATE "
+ " SET thumbnail_image = tmp.thumbnail_image"
+ " ,thumbnail_date = SYSDATE "
+ " WHEN NOT MATCHED THEN "
+ " INSERT (c_id, file_c_id, thumbnail_type, thumbnail_image, thumbnail_date) "
+ " VALUES (cedar_c_id_seq.nextval, tmp.file_c_id, tmp.thumbnail_type, tmp.thumbnail_image , SYSDATE)";
//@formatter:on
return sql;
}