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

  1. 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())).
  2. For streams call the implemented dedicated overloads directly: setBinaryStream(i, in) or setCharacterStream(i, reader) instead of setObject.
  3. 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

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


AI-assisted analysis of tursodatabase/turso@bad083fafb (2026-08-16). Data as JSON: /api/errors/e50e42c487d0e0fc. Report an issue: GitHub.