diff --git a/instrumentation/hibernate/hibernate-4.0/javaagent/src/test/groovy/CriteriaTest.groovy b/instrumentation/hibernate/hibernate-4.0/javaagent/src/test/groovy/CriteriaTest.groovy deleted file mode 100644 index f9125025d0..0000000000 --- a/instrumentation/hibernate/hibernate-4.0/javaagent/src/test/groovy/CriteriaTest.groovy +++ /dev/null @@ -1,84 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -import io.opentelemetry.javaagent.instrumentation.hibernate.v4_0.Value -import io.opentelemetry.semconv.trace.attributes.SemanticAttributes -import org.hibernate.Criteria -import org.hibernate.Session -import org.hibernate.criterion.Order -import org.hibernate.criterion.Restrictions - -import static io.opentelemetry.api.trace.SpanKind.CLIENT -import static io.opentelemetry.api.trace.SpanKind.INTERNAL - -class CriteriaTest extends AbstractHibernateTest { - - def "test criteria.#methodName"() { - setup: - runWithSpan("parent") { - Session session = sessionFactory.openSession() - session.beginTransaction() - Criteria criteria = session.createCriteria(Value) - .add(Restrictions.like("name", "Hello")) - .addOrder(Order.desc("name")) - interaction.call(criteria) - session.getTransaction().commit() - session.close() - } - - expect: - def sessionId - assertTraces(1) { - trace(0, 4) { - span(0) { - name "parent" - kind INTERNAL - hasNoParent() - attributes { - } - } - span(1) { - name "Criteria.$methodName $Value.name" - kind INTERNAL - childOf span(0) - attributes { - "hibernate.session_id" { - sessionId = it - it instanceof String - } - } - } - span(2) { - name "SELECT db1.Value" - kind CLIENT - childOf span(1) - attributes { - "$SemanticAttributes.DB_SYSTEM" "h2" - "$SemanticAttributes.DB_NAME" "db1" - "$SemanticAttributes.DB_USER" "sa" - "$SemanticAttributes.DB_CONNECTION_STRING" "h2:mem:" - "$SemanticAttributes.DB_STATEMENT" ~/^select / - "$SemanticAttributes.DB_OPERATION" "SELECT" - "$SemanticAttributes.DB_SQL_TABLE" "Value" - } - } - span(3) { - name "Transaction.commit" - kind INTERNAL - childOf span(0) - attributes { - "hibernate.session_id" sessionId - } - } - } - } - - where: - methodName | interaction - "list" | { c -> c.list() } - "uniqueResult" | { c -> c.uniqueResult() } - "scroll" | { c -> c.scroll() } - } -} diff --git a/instrumentation/hibernate/hibernate-4.0/javaagent/src/test/groovy/EntityManagerTest.groovy b/instrumentation/hibernate/hibernate-4.0/javaagent/src/test/groovy/EntityManagerTest.groovy deleted file mode 100644 index 9b5f9fc143..0000000000 --- a/instrumentation/hibernate/hibernate-4.0/javaagent/src/test/groovy/EntityManagerTest.groovy +++ /dev/null @@ -1,235 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -import io.opentelemetry.javaagent.instrumentation.hibernate.v4_0.Value -import io.opentelemetry.semconv.trace.attributes.SemanticAttributes -import spock.lang.Shared -import spock.lang.Unroll - -import javax.persistence.EntityManager -import javax.persistence.EntityManagerFactory -import javax.persistence.EntityTransaction -import javax.persistence.LockModeType -import javax.persistence.Persistence -import javax.persistence.Query - -import static io.opentelemetry.api.trace.SpanKind.CLIENT -import static io.opentelemetry.api.trace.SpanKind.INTERNAL - -class EntityManagerTest extends AbstractHibernateTest { - - @Shared - EntityManagerFactory entityManagerFactory = Persistence.createEntityManagerFactory("test-pu") - - @Unroll - def "test hibernate action #testName"() { - setup: - EntityManager entityManager = entityManagerFactory.createEntityManager() - EntityTransaction entityTransaction = entityManager.getTransaction() - entityTransaction.begin() - - def entity = prepopulated.get(0) - if (attach) { - entity = runWithSpan("setup") { - entityManager.merge(prepopulated.get(0)) - } - ignoreTracesAndClear(1) - } - - when: - runWithSpan("parent") { - try { - sessionMethodTest.call(entityManager, entity) - } catch (Exception e) { - // We expected this, we should see the error field set on the span. - } - - entityTransaction.commit() - entityManager.close() - } - - then: - boolean isPersistTest = "persist" == testName - def sessionId - assertTraces(1) { - trace(0, 4 + (isPersistTest ? 1 : 0)) { - span(0) { - name "parent" - kind INTERNAL - hasNoParent() - attributes { - } - } - span(1) { - name ~/Session.$methodName $resource/ - kind INTERNAL - childOf span(0) - attributes { - "hibernate.session_id" { - sessionId = it - it instanceof String - } - } - } - - def offset = 0 - if (isPersistTest) { - // persist test has an extra query for getting id of inserted element - offset = 1 - span(2) { - name "SELECT db1.Value" - childOf span(1) - kind CLIENT - attributes { - "$SemanticAttributes.DB_SYSTEM" "h2" - "$SemanticAttributes.DB_NAME" "db1" - "$SemanticAttributes.DB_USER" "sa" - "$SemanticAttributes.DB_CONNECTION_STRING" "h2:mem:" - "$SemanticAttributes.DB_STATEMENT" String - "$SemanticAttributes.DB_OPERATION" String - "$SemanticAttributes.DB_SQL_TABLE" "Value" - } - } - } - - if (!flushOnCommit) { - span(2 + offset) { - childOf span(1) - kind CLIENT - attributes { - "$SemanticAttributes.DB_SYSTEM" "h2" - "$SemanticAttributes.DB_NAME" "db1" - "$SemanticAttributes.DB_USER" "sa" - "$SemanticAttributes.DB_CONNECTION_STRING" "h2:mem:" - "$SemanticAttributes.DB_STATEMENT" String - "$SemanticAttributes.DB_OPERATION" String - "$SemanticAttributes.DB_SQL_TABLE" "Value" - } - } - span(3 + offset) { - name "Transaction.commit" - kind INTERNAL - childOf span(0) - attributes { - "hibernate.session_id" sessionId - } - } - } else { - span(2 + offset) { - name "Transaction.commit" - kind INTERNAL - childOf span(0) - attributes { - "hibernate.session_id" sessionId - } - } - span(3 + offset) { - childOf span(2 + offset) - kind CLIENT - attributes { - "$SemanticAttributes.DB_SYSTEM" "h2" - "$SemanticAttributes.DB_NAME" "db1" - "$SemanticAttributes.DB_USER" "sa" - "$SemanticAttributes.DB_CONNECTION_STRING" "h2:mem:" - "$SemanticAttributes.DB_STATEMENT" String - "$SemanticAttributes.DB_OPERATION" String - "$SemanticAttributes.DB_SQL_TABLE" "Value" - } - } - } - } - } - - where: - testName | methodName | resource | attach | flushOnCommit | sessionMethodTest - "lock" | "lock" | Value.name | true | false | { em, val -> - em.lock(val, LockModeType.PESSIMISTIC_READ) - } - "refresh" | "refresh" | Value.name | true | false | { em, val -> - em.refresh(val) - } - "find" | "(get|find)" | Value.name | false | false | { em, val -> - em.find(Value, val.getId()) - } - "persist" | "persist" | Value.name | false | true | { em, val -> - em.persist(new Value("insert me")) - } - "merge" | "merge" | Value.name | true | true | { em, val -> - val.setName("New name") - em.merge(val) - } - "remove" | "delete" | Value.name | true | true | { em, val -> - em.remove(val) - } - } - - @Unroll - def "test attaches State to query created via #queryMethodName"() { - setup: - runWithSpan("parent") { - EntityManager entityManager = entityManagerFactory.createEntityManager() - EntityTransaction entityTransaction = entityManager.getTransaction() - entityTransaction.begin() - Query query = queryBuildMethod(entityManager) - query.getResultList() - entityTransaction.commit() - entityManager.close() - } - - expect: - def sessionId - assertTraces(1) { - trace(0, 4) { - span(0) { - name "parent" - kind INTERNAL - hasNoParent() - attributes { - } - } - span(1) { - name resource - kind INTERNAL - childOf span(0) - attributes { - "hibernate.session_id" { - sessionId = it - it instanceof String - } - } - } - span(2) { - name "SELECT db1.Value" - kind CLIENT - childOf span(1) - attributes { - "$SemanticAttributes.DB_SYSTEM" "h2" - "$SemanticAttributes.DB_NAME" "db1" - "$SemanticAttributes.DB_USER" "sa" - "$SemanticAttributes.DB_CONNECTION_STRING" "h2:mem:" - "$SemanticAttributes.DB_STATEMENT" String - "$SemanticAttributes.DB_OPERATION" "SELECT" - "$SemanticAttributes.DB_SQL_TABLE" "Value" - } - } - span(3) { - name "Transaction.commit" - kind INTERNAL - childOf span(0) - attributes { - "hibernate.session_id" sessionId - } - } - } - } - - where: - queryMethodName | resource | queryBuildMethod - "createQuery" | "SELECT Value" | { em -> em.createQuery("from Value") } - "getNamedQuery" | "SELECT Value" | { em -> em.createNamedQuery("TestNamedQuery") } - "createSQLQuery" | "SELECT Value" | { em -> em.createNativeQuery("SELECT * FROM Value") } - } - -} diff --git a/instrumentation/hibernate/hibernate-4.0/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/hibernate/v4_0/CriteriaTest.java b/instrumentation/hibernate/hibernate-4.0/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/hibernate/v4_0/CriteriaTest.java new file mode 100644 index 0000000000..83e02ce9e5 --- /dev/null +++ b/instrumentation/hibernate/hibernate-4.0/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/hibernate/v4_0/CriteriaTest.java @@ -0,0 +1,97 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.javaagent.instrumentation.hibernate.v4_0; + +import static io.opentelemetry.api.common.AttributeKey.stringKey; +import static io.opentelemetry.api.trace.SpanKind.CLIENT; +import static io.opentelemetry.api.trace.SpanKind.INTERNAL; +import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.equalTo; +import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.satisfies; + +import io.opentelemetry.api.common.Attributes; +import io.opentelemetry.semconv.trace.attributes.SemanticAttributes; +import java.util.function.Consumer; +import java.util.stream.Stream; +import org.hibernate.Criteria; +import org.hibernate.Session; +import org.hibernate.criterion.Order; +import org.hibernate.criterion.Restrictions; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; + +class CriteriaTest extends AbstractHibernateTest { + + @ParameterizedTest + @MethodSource("provideArguments") + @SuppressWarnings("deprecation") // createCriteria(Class) has been deprecated in v5 + void testCriteria(String methodName, Consumer interaction) { + + testing.runWithSpan( + "parent", + () -> { + Session session = sessionFactory.openSession(); + session.beginTransaction(); + Criteria criteria = + session + .createCriteria(Value.class) + .add(Restrictions.like("name", "Hello")) + .addOrder(Order.desc("name")); + interaction.accept(criteria); + session.getTransaction().commit(); + session.close(); + }); + + testing.waitAndAssertTraces( + trace -> + trace.hasSpansSatisfyingExactly( + span -> + span.hasName("parent") + .hasKind(INTERNAL) + .hasNoParent() + .hasAttributes(Attributes.empty()), + span -> + span.hasName("Criteria." + methodName + " " + Value.class.getName()) + .hasKind(INTERNAL) + .hasParent(trace.getSpan(0)) + .hasAttributesSatisfyingExactly( + satisfies( + stringKey("hibernate.session_id"), + val -> val.isInstanceOf(String.class))), + span -> + span.hasName("SELECT db1.Value") + .hasKind(CLIENT) + .hasParent(trace.getSpan(1)) + .hasAttributesSatisfyingExactly( + equalTo(SemanticAttributes.DB_SYSTEM, "h2"), + equalTo(SemanticAttributes.DB_NAME, "db1"), + equalTo(SemanticAttributes.DB_USER, "sa"), + equalTo(SemanticAttributes.DB_CONNECTION_STRING, "h2:mem:"), + satisfies( + SemanticAttributes.DB_STATEMENT, + stringAssert -> stringAssert.startsWith("select")), + equalTo(SemanticAttributes.DB_OPERATION, "SELECT"), + equalTo(SemanticAttributes.DB_SQL_TABLE, "Value")), + span -> + span.hasName("Transaction.commit") + .hasKind(INTERNAL) + .hasParent(trace.getSpan(0)) + .hasAttributesSatisfyingExactly( + equalTo( + stringKey("hibernate.session_id"), + trace + .getSpan(1) + .getAttributes() + .get(stringKey("hibernate.session_id")))))); + } + + private static Stream provideArguments() { + return Stream.of( + Arguments.of("list", (Consumer) Criteria::list), + Arguments.of("uniqueResult", (Consumer) Criteria::uniqueResult), + Arguments.of("scroll", (Consumer) Criteria::scroll)); + } +} 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 new file mode 100644 index 0000000000..dee0e810a9 --- /dev/null +++ b/instrumentation/hibernate/hibernate-4.0/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/hibernate/v4_0/EntityManagerTest.java @@ -0,0 +1,350 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.javaagent.instrumentation.hibernate.v4_0; + +import static io.opentelemetry.api.common.AttributeKey.stringKey; +import static io.opentelemetry.api.trace.SpanKind.CLIENT; +import static io.opentelemetry.api.trace.SpanKind.INTERNAL; +import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.equalTo; +import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.satisfies; +import static org.junit.jupiter.api.Named.named; + +import io.opentelemetry.api.common.Attributes; +import io.opentelemetry.semconv.trace.attributes.SemanticAttributes; +import java.util.function.BiConsumer; +import java.util.function.Function; +import java.util.stream.Stream; +import javax.persistence.EntityManager; +import javax.persistence.EntityManagerFactory; +import javax.persistence.EntityTransaction; +import javax.persistence.LockModeType; +import javax.persistence.Persistence; +import javax.persistence.Query; +import org.hibernate.Version; +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; + +class EntityManagerTest extends AbstractHibernateTest { + + static final EntityManagerFactory entityManagerFactory = + Persistence.createEntityManagerFactory("test-pu"); + + @ParameterizedTest + @MethodSource("provideArgumentsHibernateActionParameters") + void testHibernateActions(Parameter parameter) { + EntityManager entityManager = entityManagerFactory.createEntityManager(); + EntityTransaction entityTransaction = entityManager.getTransaction(); + entityTransaction.begin(); + + Value entity; + if (parameter.attach) { + entity = testing.runWithSpan("setup", () -> entityManager.merge(prepopulated.get(0))); + testing.clearData(); + } else { + entity = prepopulated.get(0); + } + + String version = Version.getVersionString(); + boolean isHibernate4 = version.startsWith("4."); + boolean isLatestDep = version.startsWith("5.0"); + String action; + if ((isHibernate4 || isLatestDep) && "find".equals(parameter.methodName)) { + action = "get"; + } else { + action = parameter.methodName; + } + + testing.runWithSpan( + "parent", + () -> { + parameter.sessionMethodTest.accept(entityManager, entity); + entityTransaction.commit(); + entityManager.close(); + }); + + testing.waitAndAssertTraces( + trace -> { + if (parameter.flushOnCommit) { + trace.hasSpansSatisfyingExactly( + span -> + span.hasName("parent") + .hasKind(INTERNAL) + .hasNoParent() + .hasAttributes(Attributes.empty()), + span -> + span.hasName("Session." + action + " " + Value.class.getName()) + .hasKind(INTERNAL) + .hasParent(trace.getSpan(0)) + .hasAttributesSatisfyingExactly( + satisfies( + stringKey("hibernate.session_id"), + val -> val.isInstanceOf(String.class))), + span -> + span.hasName("Transaction.commit") + .hasKind(INTERNAL) + .hasParent(trace.getSpan(0)) + .hasAttributesSatisfyingExactly( + equalTo( + stringKey("hibernate.session_id"), + trace + .getSpan(1) + .getAttributes() + .get(stringKey("hibernate.session_id")))), + span -> + span.hasKind(CLIENT) + .hasParent(trace.getSpan(2)) + .hasAttributesSatisfyingExactly( + equalTo(SemanticAttributes.DB_SYSTEM, "h2"), + equalTo(SemanticAttributes.DB_NAME, "db1"), + equalTo(SemanticAttributes.DB_USER, "sa"), + equalTo(SemanticAttributes.DB_CONNECTION_STRING, "h2:mem:"), + satisfies( + SemanticAttributes.DB_STATEMENT, + val -> val.isInstanceOf(String.class)), + satisfies( + SemanticAttributes.DB_OPERATION, + val -> val.isInstanceOf(String.class)), + equalTo(SemanticAttributes.DB_SQL_TABLE, "Value"))); + + } else { + trace.hasSpansSatisfyingExactly( + span -> + span.hasName("parent") + .hasKind(INTERNAL) + .hasNoParent() + .hasAttributes(Attributes.empty()), + span -> + span.hasName("Session." + action + " " + Value.class.getName()) + .hasKind(INTERNAL) + .hasParent(trace.getSpan(0)) + .hasAttributesSatisfyingExactly( + satisfies( + stringKey("hibernate.session_id"), + val -> val.isInstanceOf(String.class))), + span -> + span.hasKind(CLIENT) + .hasParent(trace.getSpan(1)) + .hasAttributesSatisfyingExactly( + equalTo(SemanticAttributes.DB_SYSTEM, "h2"), + equalTo(SemanticAttributes.DB_NAME, "db1"), + equalTo(SemanticAttributes.DB_USER, "sa"), + equalTo(SemanticAttributes.DB_CONNECTION_STRING, "h2:mem:"), + satisfies( + SemanticAttributes.DB_STATEMENT, + val -> val.isInstanceOf(String.class)), + satisfies( + SemanticAttributes.DB_OPERATION, + val -> val.isInstanceOf(String.class)), + equalTo(SemanticAttributes.DB_SQL_TABLE, "Value")), + span -> + span.hasName("Transaction.commit") + .hasKind(INTERNAL) + .hasParent(trace.getSpan(0)) + .hasAttributesSatisfyingExactly( + equalTo( + stringKey("hibernate.session_id"), + trace + .getSpan(1) + .getAttributes() + .get(stringKey("hibernate.session_id"))))); + } + }); + } + + private static Stream provideArgumentsHibernateActionParameters() { + return Stream.of( + Arguments.of( + named( + "lock", + new Parameter( + "lock", true, false, (em, v) -> em.lock(v, LockModeType.PESSIMISTIC_READ)))), + Arguments.of( + named("refresh", new Parameter("refresh", true, false, EntityManager::refresh))), + Arguments.of( + named( + "find", + new Parameter("find", false, false, (em, v) -> em.find(Value.class, v.getId())))), + Arguments.of( + named( + "merge", + new Parameter( + "merge", + true, + true, + (em, v) -> { + v.setName("New name"); + em.merge(v); + }))), + Arguments.of(named("remove", new Parameter("delete", true, true, EntityManager::remove)))); + } + + @Test + void testHibernatePersist() { + EntityManager entityManager = entityManagerFactory.createEntityManager(); + EntityTransaction entityTransaction = entityManager.getTransaction(); + entityTransaction.begin(); + + testing.runWithSpan( + "parent", + () -> { + entityManager.persist(new Value("insert me")); + entityTransaction.commit(); + entityManager.close(); + }); + + testing.waitAndAssertTraces( + trace -> + trace.hasSpansSatisfyingExactly( + span -> + span.hasName("parent") + .hasKind(INTERNAL) + .hasNoParent() + .hasAttributes(Attributes.empty()), + span -> + span.hasName("Session.persist " + Value.class.getName()) + .hasKind(INTERNAL) + .hasParent(trace.getSpan(0)), + // persist test has an extra query for getting id of inserted element + span -> + span.hasName("SELECT db1.Value") + .hasKind(CLIENT) + .hasParent(trace.getSpan(1)) + .hasAttributesSatisfyingExactly( + equalTo(SemanticAttributes.DB_SYSTEM, "h2"), + equalTo(SemanticAttributes.DB_NAME, "db1"), + equalTo(SemanticAttributes.DB_USER, "sa"), + equalTo(SemanticAttributes.DB_CONNECTION_STRING, "h2:mem:"), + satisfies( + SemanticAttributes.DB_STATEMENT, + val -> val.isInstanceOf(String.class)), + satisfies( + SemanticAttributes.DB_OPERATION, + val -> val.isInstanceOf(String.class)), + equalTo(SemanticAttributes.DB_SQL_TABLE, "Value")), + span -> + span.hasName("Transaction.commit") + .hasKind(INTERNAL) + .hasParent(trace.getSpan(0)) + .hasAttributesSatisfyingExactly( + equalTo( + stringKey("hibernate.session_id"), + trace + .getSpan(1) + .getAttributes() + .get(stringKey("hibernate.session_id")))), + span -> + span.hasKind(CLIENT) + .hasParent(trace.getSpan(3)) + .hasAttributesSatisfyingExactly( + equalTo(SemanticAttributes.DB_SYSTEM, "h2"), + equalTo(SemanticAttributes.DB_NAME, "db1"), + equalTo(SemanticAttributes.DB_USER, "sa"), + equalTo(SemanticAttributes.DB_CONNECTION_STRING, "h2:mem:"), + satisfies( + SemanticAttributes.DB_STATEMENT, + val -> val.isInstanceOf(String.class)), + satisfies( + SemanticAttributes.DB_OPERATION, + val -> val.isInstanceOf(String.class)), + equalTo(SemanticAttributes.DB_SQL_TABLE, "Value")))); + } + + @ParameterizedTest + @MethodSource("provideArgumentsAttachesState") + void testAttachesStateToQuery(Function queryBuildMethod) { + testing.runWithSpan( + "parent", + () -> { + EntityManager entityManager = entityManagerFactory.createEntityManager(); + EntityTransaction entityTransaction = entityManager.getTransaction(); + entityTransaction.begin(); + queryBuildMethod.apply(entityManager).getResultList(); + entityTransaction.commit(); + entityManager.close(); + }); + + testing.waitAndAssertTraces( + trace -> + trace.hasSpansSatisfyingExactly( + span -> + span.hasName("parent") + .hasKind(INTERNAL) + .hasNoParent() + .hasAttributes(Attributes.empty()), + span -> + span.hasName("SELECT Value") + .hasKind(INTERNAL) + .hasParent(trace.getSpan(0)) + .hasAttributesSatisfyingExactly( + satisfies( + stringKey("hibernate.session_id"), + val -> val.isInstanceOf(String.class))), + span -> + span.hasName("SELECT db1.Value") + .hasKind(CLIENT) + .hasParent(trace.getSpan(1)) + .hasAttributesSatisfyingExactly( + equalTo(SemanticAttributes.DB_SYSTEM, "h2"), + equalTo(SemanticAttributes.DB_NAME, "db1"), + equalTo(SemanticAttributes.DB_USER, "sa"), + equalTo(SemanticAttributes.DB_CONNECTION_STRING, "h2:mem:"), + satisfies( + SemanticAttributes.DB_STATEMENT, + val -> val.isInstanceOf(String.class)), + satisfies( + SemanticAttributes.DB_OPERATION, + val -> val.isInstanceOf(String.class)), + equalTo(SemanticAttributes.DB_SQL_TABLE, "Value")), + span -> + span.hasName("Transaction.commit") + .hasKind(INTERNAL) + .hasParent(trace.getSpan(0)) + .hasAttributesSatisfyingExactly( + equalTo( + stringKey("hibernate.session_id"), + trace + .getSpan(1) + .getAttributes() + .get(stringKey("hibernate.session_id")))))); + } + + private static Stream provideArgumentsAttachesState() { + return Stream.of( + Arguments.of( + named( + "createQuery", + (Function) em -> em.createQuery("from Value"))), + Arguments.of( + named( + "getNamedQuery", + (Function) em -> em.createNamedQuery("TestNamedQuery"))), + Arguments.of( + named( + "createSQLQuery", + (Function) + em -> em.createNativeQuery("SELECT * FROM Value")))); + } + + private static class Parameter { + public final String methodName; + public final boolean attach; + public final boolean flushOnCommit; + public final BiConsumer sessionMethodTest; + + public Parameter( + String methodName, + boolean attach, + boolean flushOnCommit, + BiConsumer sessionMethodTest) { + this.methodName = methodName; + this.attach = attach; + this.flushOnCommit = flushOnCommit; + this.sessionMethodTest = sessionMethodTest; + } + } +}