diff --git a/instrumentation/hibernate/hibernate-4.0/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/hibernate/v4_0/EntityManagerTest.java b/instrumentation/hibernate/hibernate-4.0/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/hibernate/v4_0/EntityManagerTest.java index e964af69647c..d3bad8bdb849 100644 --- a/instrumentation/hibernate/hibernate-4.0/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/hibernate/v4_0/EntityManagerTest.java +++ b/instrumentation/hibernate/hibernate-4.0/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/hibernate/v4_0/EntityManagerTest.java @@ -19,9 +19,13 @@ import static io.opentelemetry.semconv.incubating.DbIncubatingAttributes.DB_STATEMENT; import static io.opentelemetry.semconv.incubating.DbIncubatingAttributes.DB_SYSTEM; import static io.opentelemetry.semconv.incubating.DbIncubatingAttributes.DB_USER; +import static java.util.Collections.emptyList; +import static org.assertj.core.api.Assertions.assertThatThrownBy; import static org.junit.jupiter.api.Named.named; import io.opentelemetry.api.common.Attributes; +import io.opentelemetry.api.trace.SpanKind; +import io.opentelemetry.sdk.trace.data.StatusData; import java.util.function.BiConsumer; import java.util.function.Function; import java.util.stream.Stream; @@ -29,6 +33,7 @@ import javax.persistence.EntityManagerFactory; import javax.persistence.EntityTransaction; import javax.persistence.LockModeType; +import javax.persistence.NoResultException; import javax.persistence.Persistence; import javax.persistence.Query; import org.hibernate.Version; @@ -324,6 +329,29 @@ void testAttachesStateToQuery(Function queryBuildMethod) { .get(stringKey("hibernate.session_id")))))); } + @Test + void testNoResultExceptionIgnored() { + EntityManager entityManager = entityManagerFactory.createEntityManager(); + Query query = entityManager.createQuery("from Value where id = :id"); + query.setParameter("id", 1000L); + assertThatThrownBy(query::getSingleResult).isInstanceOf(NoResultException.class); + entityManager.close(); + + testing.waitAndAssertTraces( + trace -> + trace.hasSpansSatisfyingExactly( + span -> + span.hasName("SELECT Value") + .hasKind(SpanKind.INTERNAL) + .hasNoParent() + .hasStatus(StatusData.unset()) + .hasEvents(emptyList()), + span -> + span.hasName("SELECT db1.Value") + .hasKind(SpanKind.CLIENT) + .hasParent(trace.getSpan(0)))); + } + private static Stream provideArgumentsAttachesState() { return Stream.of( Arguments.of( diff --git a/instrumentation/hibernate/hibernate-6.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/v6_0/QueryInstrumentation.java b/instrumentation/hibernate/hibernate-6.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/v6_0/QueryInstrumentation.java index 56ebecb8a2af..fa8dc951228e 100644 --- a/instrumentation/hibernate/hibernate-6.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/v6_0/QueryInstrumentation.java +++ b/instrumentation/hibernate/hibernate-6.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/v6_0/QueryInstrumentation.java @@ -45,13 +45,14 @@ public void transform(TypeTransformer transformer) { transformer.applyAdviceToMethod( isMethod() .and( + // not instrumenting getSingleResult as it calls list that is instrumented and + // we don't want to record the NoResultException that it throws namedOneOf( "list", "getResultList", "stream", "getResultStream", "uniqueResult", - "getSingleResult", "getSingleResultOrNull", "uniqueResultOptional", "executeUpdate", diff --git a/instrumentation/hibernate/hibernate-6.0/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/hibernate/v6_0/AbstractHibernateTest.java b/instrumentation/hibernate/hibernate-6.0/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/hibernate/v6_0/AbstractHibernateTest.java index 3d7e1c677cff..d297fa697412 100644 --- a/instrumentation/hibernate/hibernate-6.0/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/hibernate/v6_0/AbstractHibernateTest.java +++ b/instrumentation/hibernate/hibernate-6.0/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/hibernate/v6_0/AbstractHibernateTest.java @@ -29,7 +29,7 @@ protected static void setup() { // Pre-populate the DB, so delete/update can be tested. Session writer = sessionFactory.openSession(); writer.beginTransaction(); - prepopulated = new ArrayList(); + prepopulated = new ArrayList<>(); for (int i = 0; i < 5; i++) { prepopulated.add(new Value("Hello :) " + i)); writer.persist(prepopulated.get(i)); diff --git a/instrumentation/hibernate/hibernate-6.0/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/hibernate/v6_0/EntityManagerTest.java b/instrumentation/hibernate/hibernate-6.0/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/hibernate/v6_0/EntityManagerTest.java index 93aff1f3184e..126580bab30b 100644 --- a/instrumentation/hibernate/hibernate-6.0/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/hibernate/v6_0/EntityManagerTest.java +++ b/instrumentation/hibernate/hibernate-6.0/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/hibernate/v6_0/EntityManagerTest.java @@ -16,16 +16,20 @@ import static io.opentelemetry.semconv.incubating.DbIncubatingAttributes.DB_STATEMENT; import static io.opentelemetry.semconv.incubating.DbIncubatingAttributes.DB_SYSTEM; import static io.opentelemetry.semconv.incubating.DbIncubatingAttributes.DB_USER; +import static java.util.Collections.emptyList; +import static org.assertj.core.api.Assertions.assertThatThrownBy; import static org.junit.jupiter.api.Named.named; import io.opentelemetry.api.common.AttributeKey; import io.opentelemetry.api.trace.SpanKind; import io.opentelemetry.sdk.testing.assertj.SpanDataAssert; import io.opentelemetry.sdk.trace.data.SpanData; +import io.opentelemetry.sdk.trace.data.StatusData; import jakarta.persistence.EntityManager; import jakarta.persistence.EntityManagerFactory; import jakarta.persistence.EntityTransaction; import jakarta.persistence.LockModeType; +import jakarta.persistence.NoResultException; import jakarta.persistence.Persistence; import jakarta.persistence.Query; import java.util.Arrays; @@ -33,6 +37,7 @@ import java.util.function.BiConsumer; import java.util.function.Function; import java.util.stream.Stream; +import org.junit.jupiter.api.Test; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.Arguments; import org.junit.jupiter.params.provider.MethodSource; @@ -166,6 +171,29 @@ void testAttachesStateToQuery(Parameter parameter) { .get(AttributeKey.stringKey("hibernate.session_id"))))); } + @Test + void testNoResultExceptionIgnored() { + EntityManager entityManager = entityManagerFactory.createEntityManager(); + Query query = entityManager.createQuery("from Value where id = :id"); + query.setParameter("id", 1000); + assertThatThrownBy(query::getSingleResult).isInstanceOf(NoResultException.class); + entityManager.close(); + + testing.waitAndAssertTraces( + trace -> + trace.hasSpansSatisfyingExactly( + span -> + span.hasName("SELECT " + Value.class.getName()) + .hasKind(SpanKind.INTERNAL) + .hasNoParent() + .hasStatus(StatusData.unset()) + .hasEvents(emptyList()), + span -> + span.hasName("SELECT db1.Value") + .hasKind(SpanKind.CLIENT) + .hasParent(trace.getSpan(0)))); + } + private static Stream provideHibernateActionParameters() { List> sessionMethodTests = Arrays.asList(