Skip to content

Commit fc0bc9f

Browse files
CodingFabianclaude
andcommitted
[jdbc] Capture custom object types in prepared statement parameter instrumentation
Previously, setObject() calls with custom types (e.g. ORM-managed ID classes) were silently dropped because the instrumentation only captured a hardcoded whitelist of known JDBC types. Any class not in the list produced no parameter attribute at all, indistinguishable from a parameter that was never set. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
1 parent b0a6cdb commit fc0bc9f

2 files changed

Lines changed: 38 additions & 45 deletions

File tree

instrumentation/jdbc/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/jdbc/PreparedStatementInstrumentation.java

Lines changed: 6 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -21,13 +21,8 @@
2121
import io.opentelemetry.javaagent.bootstrap.CallDepth;
2222
import io.opentelemetry.javaagent.extension.instrumentation.TypeInstrumentation;
2323
import io.opentelemetry.javaagent.extension.instrumentation.TypeTransformer;
24-
import java.net.URL;
25-
import java.sql.Date;
2624
import java.sql.PreparedStatement;
27-
import java.sql.RowId;
2825
import java.sql.Statement;
29-
import java.sql.Time;
30-
import java.sql.Timestamp;
3126
import java.util.Calendar;
3227
import javax.annotation.Nullable;
3328
import net.bytebuddy.asm.Advice;
@@ -168,22 +163,8 @@ public static void onExit(
168163
return;
169164
}
170165

171-
String str = null;
172-
173-
if (value instanceof Boolean
174-
// Byte, Short, Int, Long, Float, Double, BigDecimal
175-
|| value instanceof Number
176-
|| value instanceof String
177-
|| value instanceof Date
178-
|| value instanceof Time
179-
|| value instanceof Timestamp
180-
|| value instanceof URL
181-
|| value instanceof RowId) {
182-
str = value.toString();
183-
}
184-
185-
if (str != null) {
186-
JdbcData.addParameter(statement, Integer.toString(index - 1), str);
166+
if (value != null) {
167+
JdbcData.addParameter(statement, Integer.toString(index - 1), value.toString());
187168
}
188169
}
189170
}
@@ -207,22 +188,8 @@ public static void onExit(
207188
return;
208189
}
209190

210-
String str = null;
211-
212-
if (value instanceof Boolean
213-
// Byte, Short, Int, Long, Float, Double, BigDecimal
214-
|| value instanceof Number
215-
|| value instanceof String
216-
|| value instanceof Date
217-
|| value instanceof Time
218-
|| value instanceof Timestamp
219-
|| value instanceof URL
220-
|| value instanceof RowId) {
221-
str = value.toString();
222-
}
223-
224-
if (str != null) {
225-
JdbcData.addParameter(statement, Integer.toString(index - 1), str);
191+
if (value != null) {
192+
JdbcData.addParameter(statement, Integer.toString(index - 1), value.toString());
226193
}
227194
}
228195
}
@@ -246,14 +213,8 @@ public static void onExit(
246213
return;
247214
}
248215

249-
String str = null;
250-
251-
if (value instanceof Date || value instanceof Time || value instanceof Timestamp) {
252-
str = value.toString();
253-
}
254-
255-
if (str != null) {
256-
JdbcData.addParameter(statement, Integer.toString(index - 1), str);
216+
if (value != null) {
217+
JdbcData.addParameter(statement, Integer.toString(index - 1), value.toString());
257218
}
258219
}
259220
}

instrumentation/jdbc/testing/src/main/java/io/opentelemetry/instrumentation/jdbc/testing/AbstractPreparedStatementParametersTest.java

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -374,6 +374,31 @@ void testObjectPreparedStatementParameter(
374374
"S");
375375
}
376376

377+
@ParameterizedTest
378+
@MethodSource("preparedStatementStream")
379+
void testCustomObjectPreparedStatementParameter(
380+
String system,
381+
Connection connection,
382+
String username,
383+
String query,
384+
String sanitizedQuery,
385+
String spanName,
386+
String url,
387+
String table)
388+
throws SQLException {
389+
test(
390+
system,
391+
connection,
392+
username,
393+
query,
394+
sanitizedQuery,
395+
spanName,
396+
url,
397+
table,
398+
statement -> statement.setObject(1, new IdType()),
399+
"id");
400+
}
401+
377402
@ParameterizedTest
378403
@MethodSource("preparedStatementStream")
379404
void testObjectWithTypePreparedStatementParameter(
@@ -658,6 +683,13 @@ DB_CONNECTION_STRING, emitStableDatabaseSemconv() ? null : url),
658683
expectedParameterValue))));
659684
}
660685

686+
private static class IdType implements java.io.Serializable {
687+
@Override
688+
public String toString() {
689+
return "id";
690+
}
691+
}
692+
661693
private interface ThrowingConsumer<T, E extends Throwable> {
662694
void accept(T t) throws E;
663695
}

0 commit comments

Comments
 (0)