tursodatabase/turso · error · SQLException
setObject does not yet support LOB or Stream types because t
Error message
setObject does not yet support LOB or Stream types because the corresponding set methods are unimplemented. Type found: {type} What it means
setObject(int, Object) in this driver supports only scalar types (null, String, Integer, Long, Boolean, Double, Float, Byte, Short, byte[], Timestamp, java.sql.Date, Time, BigDecimal). Blob, Clob, InputStream and Reader are explicitly rejected because their dedicated setters (setBlob, setClob, ...) are still unimplemented TODO stubs in JDBC4PreparedStatement, so the driver throws rather than silently no-op. The offending class name is appended to the message.
Source
Thrown at bindings/java/src/main/java/tech/turso/jdbc4/JDBC4PreparedStatement.java:311
} else if (x instanceof Byte) {
setByte(parameterIndex, (Byte) x);
} else if (x instanceof Short) {
setShort(parameterIndex, (Short) x);
} else if (x instanceof byte[]) {
setBytes(parameterIndex, (byte[]) x);
} else if (x instanceof Timestamp) {
setTimestamp(parameterIndex, (Timestamp) x);
} else if (x instanceof Date) {
setDate(parameterIndex, (Date) x);
} else if (x instanceof Time) {
setTime(parameterIndex, (Time) x);
} else if (x instanceof BigDecimal) {
setBigDecimal(parameterIndex, (BigDecimal) x);
} else if (x instanceof Blob
|| x instanceof Clob
|| x instanceof InputStream
|| x instanceof Reader) {
throw new SQLException(
"setObject does not yet support LOB or Stream types because the corresponding set methods are unimplemented. Type found: "
+ x.getClass().getName());
} else {
throw new SQLException("Unsupported object type in setObject: " + x.getClass().getName());
}
}
@Override
public boolean execute() throws SQLException {
return execute(currentBatchParams);
}
/** This helper method runs the statement using the provided parameter values. */
private boolean execute(Object[] params) throws SQLException {
// TODO: check whether this is sufficient
requireNonNull(statement);
bindParams(params);
boolean result = statement.execute();View on GitHub (pinned to bad083fafb)
Solutions
- Materialize the value and use a supported setter: Blob -> ps.setBytes(i, blob.getBytes(1, (int) blob.length())); Clob -> ps.setString(i, clob.getSubString(1, (int) clob.length())).
- For streams call the implemented dedicated overloads directly: setBinaryStream(i, in) or setCharacterStream(i, reader) instead of setObject.
- In generic layers, normalize InputStream/Reader/Blob/Clob to byte[]/String before setObject (see type guard).
Example fix
// before ps.setObject(1, new ByteArrayInputStream(data)); // throws // after ps.setBinaryStream(1, new ByteArrayInputStream(data)); // or simply ps.setBytes(1, data);
Defensive patterns
Strategy: type-guard
Validate before calling
Object v = normalizeForSetObject(raw); // InputStream/Reader -> materialize; Blob -> getBytes; Clob -> getSubString ps.setObject(i, v);
Type guard
static boolean isSetObjectLobOrStream(Object x) {
return x instanceof java.sql.Blob || x instanceof java.sql.Clob
|| x instanceof InputStream || x instanceof Reader;
} Try / catch
catch (SQLException e) {
if (e.getMessage() != null && e.getMessage().startsWith("setObject does not yet support")) {
// driver limitation: convert the named class to byte[]/String and rebind
}
throw e;
} Prevention
- Never hand LOB/stream objects to setObject with this driver; bind via dedicated setters.
- Beware: setBlob(int, Blob), setClob, setRef and setObject(int, Object, int) are silent TODO stubs — binding through them no-ops, so cover them with tests.
- Add the normalize step once in your generic DAO layer, not at each call site.
When it happens
Trigger: ps.setObject(i, blob), ps.setObject(i, clob), ps.setObject(i, inputStream), or ps.setObject(i, reader); ORMs and generic repository layers that funnel every value through setObject.
Common situations: Spring/Hibernate-style generic binders; code ported from PostgreSQL/MySQL drivers whose setObject accepted streams and LOBs; file-upload code wrapping payloads as InputStream for a 'bind anything' helper.
Related errors
- Data must have a length between 0 and Integer.MAX_VALUE
- Unsupported object type in bindObject: " + x.getClass().getN
- createClob not supported
- createBlob not supported
- createNClob not supported
AI-assisted analysis of tursodatabase/turso@bad083fafb (2026-08-16).
Data as JSON: /api/errors/e50e42c487d0e0fc.
Report an issue: GitHub.