Fix tests for hibernate 7 (#13890)
This commit is contained in:
parent
2addc6e7f7
commit
f3690c1be6
|
|
@ -28,24 +28,67 @@ dependencies {
|
||||||
testImplementation("com.sun.xml.bind:jaxb-impl:2.2.11")
|
testImplementation("com.sun.xml.bind:jaxb-impl:2.2.11")
|
||||||
testImplementation("javax.activation:activation:1.1.1")
|
testImplementation("javax.activation:activation:1.1.1")
|
||||||
testImplementation("org.hsqldb:hsqldb:2.0.0")
|
testImplementation("org.hsqldb:hsqldb:2.0.0")
|
||||||
testImplementation("org.springframework.data:spring-data-jpa:3.0.0")
|
testLibrary("org.springframework.data:spring-data-jpa:3.0.0")
|
||||||
}
|
}
|
||||||
|
|
||||||
otelJava {
|
otelJava {
|
||||||
minJavaVersionSupported.set(JavaVersion.VERSION_11)
|
minJavaVersionSupported.set(JavaVersion.VERSION_11)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
val latestDepTest = findProperty("testLatestDeps") as Boolean
|
||||||
|
|
||||||
|
testing {
|
||||||
|
suites {
|
||||||
|
val hibernate6Test by registering(JvmTestSuite::class) {
|
||||||
|
dependencies {
|
||||||
|
implementation("com.h2database:h2:1.4.197")
|
||||||
|
implementation("org.hsqldb:hsqldb:2.0.0")
|
||||||
|
if (latestDepTest) {
|
||||||
|
implementation("org.hibernate:hibernate-core:6.+")
|
||||||
|
} else {
|
||||||
|
implementation("org.hibernate:hibernate-core:6.0.0.Final")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
val hibernate7Test by registering(JvmTestSuite::class) {
|
||||||
|
dependencies {
|
||||||
|
implementation("com.h2database:h2:1.4.197")
|
||||||
|
implementation("org.hsqldb:hsqldb:2.0.0")
|
||||||
|
if (latestDepTest) {
|
||||||
|
implementation("org.hibernate:hibernate-core:7.+")
|
||||||
|
} else {
|
||||||
|
implementation("org.hibernate:hibernate-core:7.0.0.Final")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
tasks {
|
tasks {
|
||||||
withType<Test>().configureEach {
|
withType<Test>().configureEach {
|
||||||
// TODO run tests both with and without experimental span attributes
|
// TODO run tests both with and without experimental span attributes
|
||||||
jvmArgs("-Dotel.instrumentation.hibernate.experimental-span-attributes=true")
|
jvmArgs("-Dotel.instrumentation.hibernate.experimental-span-attributes=true")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
named("compileHibernate7TestJava", JavaCompile::class).configure {
|
||||||
|
options.release.set(17)
|
||||||
|
}
|
||||||
|
val testJavaVersion =
|
||||||
|
gradle.startParameter.projectProperties.get("testJavaVersion")?.let(JavaVersion::toVersion)
|
||||||
|
?: JavaVersion.current()
|
||||||
|
if (!testJavaVersion.isCompatibleWith(JavaVersion.VERSION_17)) {
|
||||||
|
named("hibernate7Test", Test::class).configure {
|
||||||
|
enabled = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
val testStableSemconv by registering(Test::class) {
|
val testStableSemconv by registering(Test::class) {
|
||||||
jvmArgs("-Dotel.semconv-stability.opt-in=database")
|
jvmArgs("-Dotel.semconv-stability.opt-in=database")
|
||||||
}
|
}
|
||||||
|
|
||||||
check {
|
check {
|
||||||
dependsOn(testStableSemconv)
|
dependsOn(testStableSemconv)
|
||||||
|
dependsOn(testing.suites)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,47 @@
|
||||||
|
/*
|
||||||
|
* Copyright The OpenTelemetry Authors
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
package io.opentelemetry.javaagent.instrumentation.hibernate.v6_0;
|
||||||
|
|
||||||
|
import io.opentelemetry.instrumentation.testing.junit.AgentInstrumentationExtension;
|
||||||
|
import io.opentelemetry.instrumentation.testing.junit.InstrumentationExtension;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import org.hibernate.Session;
|
||||||
|
import org.hibernate.SessionFactory;
|
||||||
|
import org.hibernate.cfg.Configuration;
|
||||||
|
import org.junit.jupiter.api.AfterAll;
|
||||||
|
import org.junit.jupiter.api.BeforeAll;
|
||||||
|
import org.junit.jupiter.api.extension.RegisterExtension;
|
||||||
|
|
||||||
|
abstract class AbstractHibernateTest {
|
||||||
|
protected static SessionFactory sessionFactory;
|
||||||
|
protected static List<Value> prepopulated;
|
||||||
|
|
||||||
|
@RegisterExtension
|
||||||
|
protected static final InstrumentationExtension testing = AgentInstrumentationExtension.create();
|
||||||
|
|
||||||
|
@BeforeAll
|
||||||
|
protected static void setup() {
|
||||||
|
sessionFactory = new Configuration().configure().buildSessionFactory();
|
||||||
|
// Pre-populate the DB, so delete/update can be tested.
|
||||||
|
Session writer = sessionFactory.openSession();
|
||||||
|
writer.beginTransaction();
|
||||||
|
prepopulated = new ArrayList<>();
|
||||||
|
for (int i = 0; i < 5; i++) {
|
||||||
|
prepopulated.add(new Value("Hello :) " + i));
|
||||||
|
writer.persist(prepopulated.get(i));
|
||||||
|
}
|
||||||
|
writer.getTransaction().commit();
|
||||||
|
writer.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
@AfterAll
|
||||||
|
protected static void cleanup() {
|
||||||
|
if (sessionFactory != null) {
|
||||||
|
sessionFactory.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -38,7 +38,7 @@ import org.junit.jupiter.api.BeforeAll;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
import org.junit.jupiter.api.extension.RegisterExtension;
|
import org.junit.jupiter.api.extension.RegisterExtension;
|
||||||
|
|
||||||
public class ProcedureCallTest {
|
class ProcedureCallTest {
|
||||||
protected static SessionFactory sessionFactory;
|
protected static SessionFactory sessionFactory;
|
||||||
protected static List<Value> prepopulated;
|
protected static List<Value> prepopulated;
|
||||||
|
|
||||||
|
|
@ -45,7 +45,7 @@ import org.junit.jupiter.params.provider.Arguments;
|
||||||
import org.junit.jupiter.params.provider.MethodSource;
|
import org.junit.jupiter.params.provider.MethodSource;
|
||||||
|
|
||||||
@SuppressWarnings("deprecation") // testing instrumentation of deprecated class
|
@SuppressWarnings("deprecation") // testing instrumentation of deprecated class
|
||||||
public class SessionTest extends AbstractHibernateTest {
|
class SessionTest extends AbstractHibernateTest {
|
||||||
@ParameterizedTest(name = "{index}: {0}")
|
@ParameterizedTest(name = "{index}: {0}")
|
||||||
@MethodSource("provideHibernateActionParameters")
|
@MethodSource("provideHibernateActionParameters")
|
||||||
void testHibernateAction(Parameter parameter) {
|
void testHibernateAction(Parameter parameter) {
|
||||||
|
|
@ -0,0 +1,47 @@
|
||||||
|
/*
|
||||||
|
* Copyright The OpenTelemetry Authors
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
package io.opentelemetry.javaagent.instrumentation.hibernate.v6_0;
|
||||||
|
|
||||||
|
import jakarta.persistence.Entity;
|
||||||
|
import jakarta.persistence.GeneratedValue;
|
||||||
|
import jakarta.persistence.Id;
|
||||||
|
import jakarta.persistence.Table;
|
||||||
|
import org.hibernate.annotations.GenericGenerator;
|
||||||
|
import org.hibernate.annotations.NamedQuery;
|
||||||
|
|
||||||
|
@Entity
|
||||||
|
@Table
|
||||||
|
@NamedQuery(name = "TestNamedQuery", query = "from Value")
|
||||||
|
public class Value {
|
||||||
|
|
||||||
|
private Long id;
|
||||||
|
private String name;
|
||||||
|
|
||||||
|
public Value() {}
|
||||||
|
|
||||||
|
public Value(String name) {
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Id
|
||||||
|
@GeneratedValue(generator = "increment")
|
||||||
|
@GenericGenerator(name = "increment", strategy = "increment")
|
||||||
|
public Long getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setId(Long id) {
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setName(String title) {
|
||||||
|
name = title;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,29 @@
|
||||||
|
<?xml version='1.0' encoding='utf-8'?>
|
||||||
|
<!DOCTYPE hibernate-configuration PUBLIC
|
||||||
|
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
|
||||||
|
"http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
|
||||||
|
|
||||||
|
<hibernate-configuration>
|
||||||
|
|
||||||
|
<session-factory>
|
||||||
|
|
||||||
|
<!-- Use in-memory DB for testing -->
|
||||||
|
<property name="connection.driver_class">org.h2.Driver</property>
|
||||||
|
<property name="connection.url">jdbc:h2:mem:db1;DB_CLOSE_DELAY=-1;MVCC=TRUE</property>
|
||||||
|
<property name="connection.username">sa</property>
|
||||||
|
<property name="connection.password"/>
|
||||||
|
<property name="dialect">org.hibernate.dialect.H2Dialect</property>
|
||||||
|
|
||||||
|
<property name="connection.pool_size">3</property>
|
||||||
|
<property name="cache.provider_class">org.hibernate.cache.internal.NoCacheProvider</property>
|
||||||
|
<property name="show_sql">true</property>
|
||||||
|
|
||||||
|
<!-- Reset the DB each test -->
|
||||||
|
<property name="hbm2ddl.auto">create</property>
|
||||||
|
|
||||||
|
<!-- Objects -->
|
||||||
|
<mapping class="io.opentelemetry.javaagent.instrumentation.hibernate.v6_0.Value"/>
|
||||||
|
|
||||||
|
</session-factory>
|
||||||
|
|
||||||
|
</hibernate-configuration>
|
||||||
|
|
@ -0,0 +1,47 @@
|
||||||
|
/*
|
||||||
|
* Copyright The OpenTelemetry Authors
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
package io.opentelemetry.javaagent.instrumentation.hibernate.v7_0;
|
||||||
|
|
||||||
|
import io.opentelemetry.instrumentation.testing.junit.AgentInstrumentationExtension;
|
||||||
|
import io.opentelemetry.instrumentation.testing.junit.InstrumentationExtension;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import org.hibernate.Session;
|
||||||
|
import org.hibernate.SessionFactory;
|
||||||
|
import org.hibernate.cfg.Configuration;
|
||||||
|
import org.junit.jupiter.api.AfterAll;
|
||||||
|
import org.junit.jupiter.api.BeforeAll;
|
||||||
|
import org.junit.jupiter.api.extension.RegisterExtension;
|
||||||
|
|
||||||
|
abstract class AbstractHibernateTest {
|
||||||
|
protected static SessionFactory sessionFactory;
|
||||||
|
protected static List<Value> prepopulated;
|
||||||
|
|
||||||
|
@RegisterExtension
|
||||||
|
protected static final InstrumentationExtension testing = AgentInstrumentationExtension.create();
|
||||||
|
|
||||||
|
@BeforeAll
|
||||||
|
protected static void setup() {
|
||||||
|
sessionFactory = new Configuration().configure().buildSessionFactory();
|
||||||
|
// Pre-populate the DB, so delete/update can be tested.
|
||||||
|
Session writer = sessionFactory.openSession();
|
||||||
|
writer.beginTransaction();
|
||||||
|
prepopulated = new ArrayList<>();
|
||||||
|
for (int i = 0; i < 5; i++) {
|
||||||
|
prepopulated.add(new Value("Hello :) " + i));
|
||||||
|
writer.persist(prepopulated.get(i));
|
||||||
|
}
|
||||||
|
writer.getTransaction().commit();
|
||||||
|
writer.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
@AfterAll
|
||||||
|
protected static void cleanup() {
|
||||||
|
if (sessionFactory != null) {
|
||||||
|
sessionFactory.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,193 @@
|
||||||
|
/*
|
||||||
|
* Copyright The OpenTelemetry Authors
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
package io.opentelemetry.javaagent.instrumentation.hibernate.v7_0;
|
||||||
|
|
||||||
|
import static io.opentelemetry.instrumentation.api.internal.SemconvStability.emitStableDatabaseSemconv;
|
||||||
|
import static io.opentelemetry.instrumentation.testing.junit.db.SemconvStabilityUtil.maybeStable;
|
||||||
|
import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.equalTo;
|
||||||
|
import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.satisfies;
|
||||||
|
import static io.opentelemetry.semconv.incubating.DbIncubatingAttributes.DB_CONNECTION_STRING;
|
||||||
|
import static io.opentelemetry.semconv.incubating.DbIncubatingAttributes.DB_NAME;
|
||||||
|
import static io.opentelemetry.semconv.incubating.DbIncubatingAttributes.DB_OPERATION;
|
||||||
|
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 io.opentelemetry.api.common.AttributeKey;
|
||||||
|
import io.opentelemetry.api.trace.SpanKind;
|
||||||
|
import io.opentelemetry.instrumentation.testing.junit.AgentInstrumentationExtension;
|
||||||
|
import io.opentelemetry.instrumentation.testing.junit.InstrumentationExtension;
|
||||||
|
import io.opentelemetry.sdk.trace.data.StatusData;
|
||||||
|
import jakarta.persistence.ParameterMode;
|
||||||
|
import java.sql.Connection;
|
||||||
|
import java.sql.DriverManager;
|
||||||
|
import java.sql.SQLException;
|
||||||
|
import java.sql.Statement;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import org.hibernate.Session;
|
||||||
|
import org.hibernate.SessionFactory;
|
||||||
|
import org.hibernate.cfg.Configuration;
|
||||||
|
import org.hibernate.procedure.ProcedureCall;
|
||||||
|
import org.hibernate.procedure.ProcedureParameter;
|
||||||
|
import org.junit.jupiter.api.AfterAll;
|
||||||
|
import org.junit.jupiter.api.BeforeAll;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.junit.jupiter.api.extension.RegisterExtension;
|
||||||
|
|
||||||
|
class ProcedureCallTest {
|
||||||
|
protected static SessionFactory sessionFactory;
|
||||||
|
protected static List<Value> prepopulated;
|
||||||
|
|
||||||
|
@RegisterExtension
|
||||||
|
protected static final InstrumentationExtension testing = AgentInstrumentationExtension.create();
|
||||||
|
|
||||||
|
@BeforeAll
|
||||||
|
static void setup() throws SQLException {
|
||||||
|
sessionFactory =
|
||||||
|
new Configuration().configure("procedure-call-hibernate.cfg.xml").buildSessionFactory();
|
||||||
|
// Pre-populate the DB, so delete/update can be tested.
|
||||||
|
Session writer = sessionFactory.openSession();
|
||||||
|
writer.beginTransaction();
|
||||||
|
prepopulated = new ArrayList<>();
|
||||||
|
for (int i = 0; i < 2; i++) {
|
||||||
|
prepopulated.add(new Value("Hello :) " + i));
|
||||||
|
writer.persist(prepopulated.get(i));
|
||||||
|
}
|
||||||
|
writer.getTransaction().commit();
|
||||||
|
writer.close();
|
||||||
|
|
||||||
|
// Create a stored procedure.
|
||||||
|
Connection conn = DriverManager.getConnection("jdbc:hsqldb:mem:test", "sa", "1");
|
||||||
|
Statement stmt = conn.createStatement();
|
||||||
|
stmt.execute(
|
||||||
|
"CREATE PROCEDURE TEST_PROC() MODIFIES SQL DATA BEGIN ATOMIC INSERT INTO Value VALUES (420, 'fred'); END");
|
||||||
|
stmt.close();
|
||||||
|
conn.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
@AfterAll
|
||||||
|
static void cleanup() {
|
||||||
|
if (sessionFactory != null) {
|
||||||
|
sessionFactory.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("deprecation") // TODO DB_CONNECTION_STRING deprecation
|
||||||
|
@Test
|
||||||
|
void testProcedureCall() {
|
||||||
|
testing.runWithSpan(
|
||||||
|
"parent",
|
||||||
|
() -> {
|
||||||
|
Session session = sessionFactory.openSession();
|
||||||
|
session.beginTransaction();
|
||||||
|
|
||||||
|
ProcedureCall call = session.createStoredProcedureCall("TEST_PROC");
|
||||||
|
call.getOutputs();
|
||||||
|
|
||||||
|
session.getTransaction().commit();
|
||||||
|
session.close();
|
||||||
|
});
|
||||||
|
|
||||||
|
testing.waitAndAssertTraces(
|
||||||
|
trace ->
|
||||||
|
trace.hasSpansSatisfyingExactly(
|
||||||
|
span -> span.hasName("parent").hasKind(SpanKind.INTERNAL).hasNoParent(),
|
||||||
|
span ->
|
||||||
|
span.hasName("ProcedureCall.getOutputs TEST_PROC")
|
||||||
|
.hasKind(SpanKind.INTERNAL)
|
||||||
|
.hasParent(trace.getSpan(0))
|
||||||
|
.hasAttributesSatisfyingExactly(
|
||||||
|
satisfies(
|
||||||
|
AttributeKey.stringKey("hibernate.session_id"),
|
||||||
|
val -> val.isInstanceOf(String.class))),
|
||||||
|
span ->
|
||||||
|
span.hasName("CALL test.TEST_PROC")
|
||||||
|
.hasKind(SpanKind.CLIENT)
|
||||||
|
.hasParent(trace.getSpan(1))
|
||||||
|
.hasAttributesSatisfyingExactly(
|
||||||
|
equalTo(maybeStable(DB_SYSTEM), "hsqldb"),
|
||||||
|
equalTo(maybeStable(DB_NAME), "test"),
|
||||||
|
equalTo(DB_USER, emitStableDatabaseSemconv() ? null : "sa"),
|
||||||
|
equalTo(
|
||||||
|
DB_CONNECTION_STRING,
|
||||||
|
emitStableDatabaseSemconv() ? null : "hsqldb:mem:"),
|
||||||
|
equalTo(maybeStable(DB_STATEMENT), "{call TEST_PROC()}"),
|
||||||
|
equalTo(maybeStable(DB_OPERATION), "CALL")),
|
||||||
|
span ->
|
||||||
|
span.hasName("Transaction.commit")
|
||||||
|
.hasKind(SpanKind.INTERNAL)
|
||||||
|
.hasParent(trace.getSpan(0))
|
||||||
|
.hasAttributesSatisfyingExactly(
|
||||||
|
equalTo(
|
||||||
|
AttributeKey.stringKey("hibernate.session_id"),
|
||||||
|
trace
|
||||||
|
.getSpan(1)
|
||||||
|
.getAttributes()
|
||||||
|
.get(AttributeKey.stringKey("hibernate.session_id"))))));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testFailingProcedureCall() {
|
||||||
|
testing.runWithSpan(
|
||||||
|
"parent",
|
||||||
|
() -> {
|
||||||
|
Session session = sessionFactory.openSession();
|
||||||
|
session.beginTransaction();
|
||||||
|
|
||||||
|
ProcedureCall call = session.createStoredProcedureCall("TEST_PROC");
|
||||||
|
ProcedureParameter<Long> parameterRegistration =
|
||||||
|
call.registerParameter("nonexistent", Long.class, ParameterMode.IN);
|
||||||
|
call.setParameter(parameterRegistration, 420L);
|
||||||
|
try {
|
||||||
|
call.getOutputs();
|
||||||
|
} catch (RuntimeException e) {
|
||||||
|
// We expected this.
|
||||||
|
}
|
||||||
|
session.getTransaction().commit();
|
||||||
|
session.close();
|
||||||
|
});
|
||||||
|
|
||||||
|
testing.waitAndAssertTraces(
|
||||||
|
trace ->
|
||||||
|
trace.hasSpansSatisfyingExactly(
|
||||||
|
span -> span.hasName("parent").hasKind(SpanKind.INTERNAL).hasNoParent(),
|
||||||
|
span ->
|
||||||
|
span.hasName("ProcedureCall.getOutputs TEST_PROC")
|
||||||
|
.hasKind(SpanKind.INTERNAL)
|
||||||
|
.hasParent(trace.getSpan(0))
|
||||||
|
.hasStatus(StatusData.error())
|
||||||
|
.hasEventsSatisfyingExactly(
|
||||||
|
event ->
|
||||||
|
event
|
||||||
|
.hasName("exception")
|
||||||
|
.hasAttributesSatisfyingExactly(
|
||||||
|
equalTo(
|
||||||
|
AttributeKey.stringKey("exception.type"),
|
||||||
|
"org.hibernate.exception.AuthException"),
|
||||||
|
satisfies(
|
||||||
|
AttributeKey.stringKey("exception.message"),
|
||||||
|
val -> val.startsWith("could not prepare statement")),
|
||||||
|
satisfies(
|
||||||
|
AttributeKey.stringKey("exception.stacktrace"),
|
||||||
|
val -> val.isNotNull())))
|
||||||
|
.hasAttributesSatisfyingExactly(
|
||||||
|
satisfies(
|
||||||
|
AttributeKey.stringKey("hibernate.session_id"),
|
||||||
|
val -> val.isInstanceOf(String.class))),
|
||||||
|
span ->
|
||||||
|
span.hasName("Transaction.commit")
|
||||||
|
.hasKind(SpanKind.INTERNAL)
|
||||||
|
.hasParent(trace.getSpan(0))
|
||||||
|
.hasAttributesSatisfyingExactly(
|
||||||
|
equalTo(
|
||||||
|
AttributeKey.stringKey("hibernate.session_id"),
|
||||||
|
trace
|
||||||
|
.getSpan(1)
|
||||||
|
.getAttributes()
|
||||||
|
.get(AttributeKey.stringKey("hibernate.session_id"))))));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,756 @@
|
||||||
|
/*
|
||||||
|
* Copyright The OpenTelemetry Authors
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
package io.opentelemetry.javaagent.instrumentation.hibernate.v7_0;
|
||||||
|
|
||||||
|
import static io.opentelemetry.instrumentation.api.internal.SemconvStability.emitStableDatabaseSemconv;
|
||||||
|
import static io.opentelemetry.instrumentation.testing.junit.db.SemconvStabilityUtil.maybeStable;
|
||||||
|
import static io.opentelemetry.instrumentation.testing.junit.db.SemconvStabilityUtil.maybeStableDbSystemName;
|
||||||
|
import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.equalTo;
|
||||||
|
import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.satisfies;
|
||||||
|
import static io.opentelemetry.semconv.incubating.DbIncubatingAttributes.DB_CONNECTION_STRING;
|
||||||
|
import static io.opentelemetry.semconv.incubating.DbIncubatingAttributes.DB_NAME;
|
||||||
|
import static io.opentelemetry.semconv.incubating.DbIncubatingAttributes.DB_OPERATION;
|
||||||
|
import static io.opentelemetry.semconv.incubating.DbIncubatingAttributes.DB_SQL_TABLE;
|
||||||
|
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 org.junit.jupiter.api.Assertions.assertNotEquals;
|
||||||
|
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.Timeout;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Locale;
|
||||||
|
import java.util.concurrent.atomic.AtomicReference;
|
||||||
|
import java.util.function.BiConsumer;
|
||||||
|
import java.util.function.Consumer;
|
||||||
|
import java.util.function.Function;
|
||||||
|
import java.util.stream.Stream;
|
||||||
|
import org.hibernate.LockMode;
|
||||||
|
import org.hibernate.ReplicationMode;
|
||||||
|
import org.hibernate.Session;
|
||||||
|
import org.hibernate.StatelessSession;
|
||||||
|
import org.hibernate.UnknownEntityTypeException;
|
||||||
|
import org.hibernate.query.SelectionQuery;
|
||||||
|
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;
|
||||||
|
|
||||||
|
@SuppressWarnings("deprecation") // testing instrumentation of deprecated class
|
||||||
|
class SessionTest extends AbstractHibernateTest {
|
||||||
|
@ParameterizedTest(name = "{index}: {0}")
|
||||||
|
@MethodSource("provideHibernateActionParameters")
|
||||||
|
void testHibernateAction(Parameter parameter) {
|
||||||
|
Session session = sessionFactory.openSession();
|
||||||
|
Value value = session.merge(prepopulated.get(0));
|
||||||
|
testing.waitForTraces(1);
|
||||||
|
testing.clearData();
|
||||||
|
|
||||||
|
testing.runWithSpan(
|
||||||
|
"parent",
|
||||||
|
() -> {
|
||||||
|
session.beginTransaction();
|
||||||
|
try {
|
||||||
|
parameter.sessionMethodTest.accept(session, value);
|
||||||
|
} catch (RuntimeException e) {
|
||||||
|
// We expected this, we should see the error field set on the span.
|
||||||
|
}
|
||||||
|
session.getTransaction().commit();
|
||||||
|
session.close();
|
||||||
|
});
|
||||||
|
assertTraces(parameter, "refresh".equals(parameter.methodName));
|
||||||
|
}
|
||||||
|
|
||||||
|
@ParameterizedTest(name = "{index}: {0}")
|
||||||
|
@MethodSource("provideHibernateActionWithStatelessSessionParameters")
|
||||||
|
void testHibernateActionStatelessSession(Parameter parameter) {
|
||||||
|
testing.runWithSpan(
|
||||||
|
"parent",
|
||||||
|
() -> {
|
||||||
|
StatelessSession session = sessionFactory.openStatelessSession();
|
||||||
|
session.beginTransaction();
|
||||||
|
try {
|
||||||
|
parameter.statelessSessionMethodTest.accept(session, prepopulated.get(0));
|
||||||
|
} catch (RuntimeException e) {
|
||||||
|
// We expected this, we should see the error field set on the span.
|
||||||
|
}
|
||||||
|
session.getTransaction().commit();
|
||||||
|
session.close();
|
||||||
|
});
|
||||||
|
assertTraces(parameter, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void assertTraces(Parameter parameter, boolean hasClientSpan) {
|
||||||
|
testing.waitAndAssertTraces(
|
||||||
|
trace -> {
|
||||||
|
List<Consumer<SpanDataAssert>> assertions = new ArrayList<>();
|
||||||
|
assertions.add(span -> span.hasName("parent").hasKind(SpanKind.INTERNAL).hasNoParent());
|
||||||
|
assertions.add(
|
||||||
|
span ->
|
||||||
|
assertSessionSpan(
|
||||||
|
span,
|
||||||
|
trace.getSpan(0),
|
||||||
|
"Session." + parameter.methodName + " " + parameter.resource));
|
||||||
|
if (hasClientSpan) {
|
||||||
|
assertions.add(span -> assertClientSpan(span, trace.getSpan(1)));
|
||||||
|
}
|
||||||
|
assertions.add(
|
||||||
|
span ->
|
||||||
|
assertSpanWithSessionId(
|
||||||
|
span,
|
||||||
|
trace.getSpan(0),
|
||||||
|
"Transaction.commit",
|
||||||
|
trace
|
||||||
|
.getSpan(1)
|
||||||
|
.getAttributes()
|
||||||
|
.get(AttributeKey.stringKey("hibernate.session_id"))));
|
||||||
|
|
||||||
|
trace.hasSpansSatisfyingExactly(assertions);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@ParameterizedTest(name = "{index}: {0}")
|
||||||
|
@MethodSource("provideHibernateReplicateParameters")
|
||||||
|
void testHibernateReplicate(Parameter parameter) {
|
||||||
|
testing.runWithSpan(
|
||||||
|
"parent",
|
||||||
|
() -> {
|
||||||
|
Session session = sessionFactory.openSession();
|
||||||
|
session.beginTransaction();
|
||||||
|
try {
|
||||||
|
parameter.sessionMethodTest.accept(session, prepopulated.get(0));
|
||||||
|
} catch (RuntimeException e) {
|
||||||
|
// We expected this, we should see the error field set on the span.
|
||||||
|
}
|
||||||
|
session.getTransaction().commit();
|
||||||
|
session.close();
|
||||||
|
});
|
||||||
|
|
||||||
|
testing.waitAndAssertTraces(
|
||||||
|
trace ->
|
||||||
|
trace.hasSpansSatisfyingExactly(
|
||||||
|
span -> span.hasName("parent").hasKind(SpanKind.INTERNAL).hasNoParent(),
|
||||||
|
span ->
|
||||||
|
assertSessionSpan(
|
||||||
|
span,
|
||||||
|
trace.getSpan(0),
|
||||||
|
"Session." + parameter.methodName + " " + parameter.resource),
|
||||||
|
span -> assertClientSpan(span, trace.getSpan(1), "SELECT"),
|
||||||
|
span ->
|
||||||
|
assertSpanWithSessionId(
|
||||||
|
span,
|
||||||
|
trace.getSpan(0),
|
||||||
|
"Transaction.commit",
|
||||||
|
trace
|
||||||
|
.getSpan(1)
|
||||||
|
.getAttributes()
|
||||||
|
.get(AttributeKey.stringKey("hibernate.session_id"))),
|
||||||
|
span -> assertClientSpan(span, trace.getSpan(3))));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testHibernateFailedReplicate() {
|
||||||
|
testing.runWithSpan(
|
||||||
|
"parent",
|
||||||
|
() -> {
|
||||||
|
Session session = sessionFactory.openSession();
|
||||||
|
session.beginTransaction();
|
||||||
|
try {
|
||||||
|
session.replicate(
|
||||||
|
Long.valueOf(123) /* Not a valid entity */, ReplicationMode.OVERWRITE);
|
||||||
|
} catch (RuntimeException e) {
|
||||||
|
// We expected this, we should see the error field set on the span.
|
||||||
|
}
|
||||||
|
session.getTransaction().commit();
|
||||||
|
session.close();
|
||||||
|
});
|
||||||
|
|
||||||
|
testing.waitAndAssertTraces(
|
||||||
|
trace ->
|
||||||
|
trace.hasSpansSatisfyingExactly(
|
||||||
|
span -> span.hasName("parent").hasKind(SpanKind.INTERNAL).hasNoParent(),
|
||||||
|
span ->
|
||||||
|
span.hasName("Session.replicate java.lang.Long")
|
||||||
|
.hasKind(SpanKind.INTERNAL)
|
||||||
|
.hasParent(trace.getSpan(0))
|
||||||
|
.hasStatus(StatusData.error())
|
||||||
|
.hasException(new UnknownEntityTypeException("java.lang.Long"))
|
||||||
|
.hasAttributesSatisfyingExactly(
|
||||||
|
satisfies(
|
||||||
|
AttributeKey.stringKey("hibernate.session_id"),
|
||||||
|
val -> val.isInstanceOf(String.class))),
|
||||||
|
span ->
|
||||||
|
assertSpanWithSessionId(
|
||||||
|
span,
|
||||||
|
trace.getSpan(0),
|
||||||
|
"Transaction.commit",
|
||||||
|
trace
|
||||||
|
.getSpan(1)
|
||||||
|
.getAttributes()
|
||||||
|
.get(AttributeKey.stringKey("hibernate.session_id")))));
|
||||||
|
}
|
||||||
|
|
||||||
|
@ParameterizedTest(name = "{index}: {0}")
|
||||||
|
@MethodSource("provideHibernateCommitActionParameters")
|
||||||
|
void testHibernateCommitAction(Parameter parameter) {
|
||||||
|
testing.runWithSpan(
|
||||||
|
"parent",
|
||||||
|
() -> {
|
||||||
|
Session session = sessionFactory.openSession();
|
||||||
|
session.beginTransaction();
|
||||||
|
try {
|
||||||
|
parameter.sessionMethodTest.accept(session, prepopulated.get(0));
|
||||||
|
} catch (RuntimeException e) {
|
||||||
|
// We expected this, we should see the error field set on the span.
|
||||||
|
}
|
||||||
|
session.getTransaction().commit();
|
||||||
|
session.close();
|
||||||
|
});
|
||||||
|
|
||||||
|
testing.waitAndAssertTraces(
|
||||||
|
trace ->
|
||||||
|
trace.hasSpansSatisfyingExactly(
|
||||||
|
span -> span.hasName("parent").hasKind(SpanKind.INTERNAL).hasNoParent(),
|
||||||
|
span ->
|
||||||
|
assertSessionSpan(
|
||||||
|
span,
|
||||||
|
trace.getSpan(0),
|
||||||
|
"Session." + parameter.methodName + " " + parameter.resource),
|
||||||
|
span ->
|
||||||
|
assertSpanWithSessionId(
|
||||||
|
span,
|
||||||
|
trace.getSpan(0),
|
||||||
|
"Transaction.commit",
|
||||||
|
trace
|
||||||
|
.getSpan(1)
|
||||||
|
.getAttributes()
|
||||||
|
.get(AttributeKey.stringKey("hibernate.session_id"))),
|
||||||
|
span -> assertClientSpan(span, trace.getSpan(2))));
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("deprecation") // TODO DB_CONNECTION_STRING deprecation
|
||||||
|
@ParameterizedTest(name = "{index}: {0}")
|
||||||
|
@MethodSource("provideAttachesStateToQueryParameters")
|
||||||
|
void testAttachesStateToQuery(Parameter parameter) {
|
||||||
|
testing.runWithSpan(
|
||||||
|
"parent",
|
||||||
|
() -> {
|
||||||
|
Session session = sessionFactory.openSession();
|
||||||
|
session.beginTransaction();
|
||||||
|
SelectionQuery<?> query = parameter.queryBuildMethod.apply(session);
|
||||||
|
query.list();
|
||||||
|
session.getTransaction().commit();
|
||||||
|
session.close();
|
||||||
|
});
|
||||||
|
|
||||||
|
testing.waitAndAssertTraces(
|
||||||
|
trace ->
|
||||||
|
trace.hasSpansSatisfyingExactly(
|
||||||
|
span -> span.hasName("parent").hasKind(SpanKind.INTERNAL).hasNoParent(),
|
||||||
|
span -> assertSessionSpan(span, trace.getSpan(0), parameter.resource),
|
||||||
|
span ->
|
||||||
|
span.hasKind(SpanKind.CLIENT)
|
||||||
|
.hasParent(trace.getSpan(1))
|
||||||
|
.hasAttributesSatisfyingExactly(
|
||||||
|
equalTo(maybeStable(DB_SYSTEM), maybeStableDbSystemName("h2")),
|
||||||
|
equalTo(maybeStable(DB_NAME), "db1"),
|
||||||
|
equalTo(DB_USER, emitStableDatabaseSemconv() ? null : "sa"),
|
||||||
|
equalTo(
|
||||||
|
DB_CONNECTION_STRING,
|
||||||
|
emitStableDatabaseSemconv() ? null : "h2:mem:"),
|
||||||
|
satisfies(
|
||||||
|
maybeStable(DB_STATEMENT), val -> val.isInstanceOf(String.class)),
|
||||||
|
equalTo(maybeStable(DB_OPERATION), "SELECT"),
|
||||||
|
equalTo(maybeStable(DB_SQL_TABLE), "Value")),
|
||||||
|
span ->
|
||||||
|
assertSpanWithSessionId(
|
||||||
|
span,
|
||||||
|
trace.getSpan(0),
|
||||||
|
"Transaction.commit",
|
||||||
|
trace
|
||||||
|
.getSpan(1)
|
||||||
|
.getAttributes()
|
||||||
|
.get(AttributeKey.stringKey("hibernate.session_id")))));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testHibernateOverlappingSessions() {
|
||||||
|
AtomicReference<String> sessionId1 = new AtomicReference<>();
|
||||||
|
AtomicReference<String> sessionId2 = new AtomicReference<>();
|
||||||
|
AtomicReference<String> sessionId3 = new AtomicReference<>();
|
||||||
|
|
||||||
|
testing.runWithSpan(
|
||||||
|
"overlapping Sessions",
|
||||||
|
() -> {
|
||||||
|
Session session1 = sessionFactory.openSession();
|
||||||
|
session1.beginTransaction();
|
||||||
|
StatelessSession session2 = sessionFactory.openStatelessSession();
|
||||||
|
Session session3 = sessionFactory.openSession();
|
||||||
|
|
||||||
|
Value value1 = new Value("Value 1");
|
||||||
|
session1.merge(value1);
|
||||||
|
session2.insert(new Value("Value 2"));
|
||||||
|
session3.merge(new Value("Value 3"));
|
||||||
|
session1.remove(value1);
|
||||||
|
|
||||||
|
session2.close();
|
||||||
|
session1.getTransaction().commit();
|
||||||
|
session1.close();
|
||||||
|
session3.close();
|
||||||
|
});
|
||||||
|
|
||||||
|
testing.waitAndAssertTraces(
|
||||||
|
trace ->
|
||||||
|
trace.hasSpansSatisfyingExactly(
|
||||||
|
span -> span.hasName("overlapping Sessions"),
|
||||||
|
span -> {
|
||||||
|
assertSessionSpan(
|
||||||
|
span,
|
||||||
|
trace.getSpan(0),
|
||||||
|
"Session.merge io.opentelemetry.javaagent.instrumentation.hibernate.v7_0.Value");
|
||||||
|
sessionId1.set(
|
||||||
|
trace
|
||||||
|
.getSpan(1)
|
||||||
|
.getAttributes()
|
||||||
|
.get(AttributeKey.stringKey("hibernate.session_id")));
|
||||||
|
},
|
||||||
|
span -> {
|
||||||
|
assertSessionSpan(
|
||||||
|
span,
|
||||||
|
trace.getSpan(0),
|
||||||
|
"Session.insert io.opentelemetry.javaagent.instrumentation.hibernate.v7_0.Value");
|
||||||
|
sessionId2.set(
|
||||||
|
trace
|
||||||
|
.getSpan(2)
|
||||||
|
.getAttributes()
|
||||||
|
.get(AttributeKey.stringKey("hibernate.session_id")));
|
||||||
|
},
|
||||||
|
span -> assertClientSpan(span, trace.getSpan(2), "INSERT"),
|
||||||
|
span -> {
|
||||||
|
assertSessionSpan(
|
||||||
|
span,
|
||||||
|
trace.getSpan(0),
|
||||||
|
"Session.merge io.opentelemetry.javaagent.instrumentation.hibernate.v7_0.Value");
|
||||||
|
sessionId3.set(
|
||||||
|
trace
|
||||||
|
.getSpan(4)
|
||||||
|
.getAttributes()
|
||||||
|
.get(AttributeKey.stringKey("hibernate.session_id")));
|
||||||
|
},
|
||||||
|
span ->
|
||||||
|
assertSpanWithSessionId(
|
||||||
|
span,
|
||||||
|
trace.getSpan(0),
|
||||||
|
"Session.remove io.opentelemetry.javaagent.instrumentation.hibernate.v7_0.Value",
|
||||||
|
sessionId1.get()),
|
||||||
|
span ->
|
||||||
|
assertSpanWithSessionId(
|
||||||
|
span, trace.getSpan(0), "Transaction.commit", sessionId1.get()),
|
||||||
|
span -> assertClientSpan(span, trace.getSpan(6), "INSERT")));
|
||||||
|
|
||||||
|
assertNotEquals(sessionId1.get(), sessionId2.get());
|
||||||
|
assertNotEquals(sessionId2.get(), sessionId3.get());
|
||||||
|
assertNotEquals(sessionId1.get(), sessionId3.get());
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Stream<Arguments> provideHibernateActionParameters() {
|
||||||
|
List<BiConsumer<Session, Value>> sessionMethodTests =
|
||||||
|
Arrays.asList(
|
||||||
|
(session, val) -> session.lock(val, LockMode.READ),
|
||||||
|
(session, val) -> session.lock(val, LockMode.READ, Timeout.seconds(1)),
|
||||||
|
(session, val) -> session.refresh(val),
|
||||||
|
(session, val) -> session.find(Value.class, val.getId()));
|
||||||
|
|
||||||
|
return Stream.of(
|
||||||
|
Arguments.of(
|
||||||
|
named(
|
||||||
|
"lock",
|
||||||
|
new Parameter(
|
||||||
|
"lock",
|
||||||
|
"io.opentelemetry.javaagent.instrumentation.hibernate.v7_0.Value",
|
||||||
|
null,
|
||||||
|
sessionMethodTests.get(0),
|
||||||
|
null))),
|
||||||
|
Arguments.of(
|
||||||
|
named(
|
||||||
|
"lock with options",
|
||||||
|
new Parameter(
|
||||||
|
"lock",
|
||||||
|
"io.opentelemetry.javaagent.instrumentation.hibernate.v7_0.Value",
|
||||||
|
null,
|
||||||
|
sessionMethodTests.get(1),
|
||||||
|
null))),
|
||||||
|
Arguments.of(
|
||||||
|
named(
|
||||||
|
"refresh",
|
||||||
|
new Parameter(
|
||||||
|
"refresh",
|
||||||
|
"io.opentelemetry.javaagent.instrumentation.hibernate.v7_0.Value",
|
||||||
|
null,
|
||||||
|
sessionMethodTests.get(2),
|
||||||
|
null))),
|
||||||
|
Arguments.of(
|
||||||
|
named(
|
||||||
|
"find",
|
||||||
|
new Parameter(
|
||||||
|
"find",
|
||||||
|
"io.opentelemetry.javaagent.instrumentation.hibernate.v7_0.Value",
|
||||||
|
null,
|
||||||
|
sessionMethodTests.get(3),
|
||||||
|
null))));
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Stream<Arguments> provideHibernateActionWithStatelessSessionParameters() {
|
||||||
|
List<BiConsumer<StatelessSession, Value>> statelessSessionMethodTests =
|
||||||
|
Arrays.asList(
|
||||||
|
(statelessSession, val) -> statelessSession.refresh(val),
|
||||||
|
(statelessSession, val) ->
|
||||||
|
statelessSession.refresh(
|
||||||
|
"io.opentelemetry.javaagent.instrumentation.hibernate.v7_0.Value", val),
|
||||||
|
(statelessSession, val) ->
|
||||||
|
statelessSession.get(
|
||||||
|
"io.opentelemetry.javaagent.instrumentation.hibernate.v7_0.Value", val.getId()),
|
||||||
|
(statelessSession, val) -> statelessSession.get(Value.class, val.getId()),
|
||||||
|
(statelessSession, val) -> statelessSession.insert(new Value("insert me")),
|
||||||
|
(statelessSession, val) ->
|
||||||
|
statelessSession.insert(
|
||||||
|
"io.opentelemetry.javaagent.instrumentation.hibernate.v7_0.Value",
|
||||||
|
new Value("insert me")),
|
||||||
|
(statelessSession, val) -> statelessSession.insert(null, new Value("insert me")),
|
||||||
|
(statelessSession, val) -> {
|
||||||
|
val.setName("New name");
|
||||||
|
statelessSession.update(val);
|
||||||
|
},
|
||||||
|
(statelessSession, val) -> {
|
||||||
|
val.setName("New name");
|
||||||
|
statelessSession.update(
|
||||||
|
"io.opentelemetry.javaagent.instrumentation.hibernate.v7_0.Value", val);
|
||||||
|
},
|
||||||
|
(statelessSession, val) -> {
|
||||||
|
statelessSession.delete(val);
|
||||||
|
prepopulated.remove(val);
|
||||||
|
},
|
||||||
|
(statelessSession, val) -> {
|
||||||
|
statelessSession.delete(
|
||||||
|
"io.opentelemetry.javaagent.instrumentation.hibernate.v7_0.Value", val);
|
||||||
|
prepopulated.remove(val);
|
||||||
|
});
|
||||||
|
|
||||||
|
return Stream.of(
|
||||||
|
Arguments.of(
|
||||||
|
named(
|
||||||
|
"refresh",
|
||||||
|
new Parameter(
|
||||||
|
"refresh",
|
||||||
|
"io.opentelemetry.javaagent.instrumentation.hibernate.v7_0.Value",
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
statelessSessionMethodTests.get(0)))),
|
||||||
|
Arguments.of(
|
||||||
|
named(
|
||||||
|
"refresh with entity name",
|
||||||
|
new Parameter(
|
||||||
|
"refresh",
|
||||||
|
"io.opentelemetry.javaagent.instrumentation.hibernate.v7_0.Value",
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
statelessSessionMethodTests.get(1)))),
|
||||||
|
Arguments.of(
|
||||||
|
named(
|
||||||
|
"get with entity name",
|
||||||
|
new Parameter(
|
||||||
|
"get",
|
||||||
|
"io.opentelemetry.javaagent.instrumentation.hibernate.v7_0.Value",
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
statelessSessionMethodTests.get(2)))),
|
||||||
|
Arguments.of(
|
||||||
|
named(
|
||||||
|
"get with entity class",
|
||||||
|
new Parameter(
|
||||||
|
"get",
|
||||||
|
"io.opentelemetry.javaagent.instrumentation.hibernate.v7_0.Value",
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
statelessSessionMethodTests.get(3)))),
|
||||||
|
Arguments.of(
|
||||||
|
named(
|
||||||
|
"insert",
|
||||||
|
new Parameter(
|
||||||
|
"insert",
|
||||||
|
"io.opentelemetry.javaagent.instrumentation.hibernate.v7_0.Value",
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
statelessSessionMethodTests.get(4)))),
|
||||||
|
Arguments.of(
|
||||||
|
named(
|
||||||
|
"insert with entity name",
|
||||||
|
new Parameter(
|
||||||
|
"insert",
|
||||||
|
"io.opentelemetry.javaagent.instrumentation.hibernate.v7_0.Value",
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
statelessSessionMethodTests.get(5)))),
|
||||||
|
Arguments.of(
|
||||||
|
named(
|
||||||
|
"insert with null entity name",
|
||||||
|
new Parameter(
|
||||||
|
"insert",
|
||||||
|
"io.opentelemetry.javaagent.instrumentation.hibernate.v7_0.Value",
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
statelessSessionMethodTests.get(6)))),
|
||||||
|
Arguments.of(
|
||||||
|
named(
|
||||||
|
"update (StatelessSession)",
|
||||||
|
new Parameter(
|
||||||
|
"update",
|
||||||
|
"io.opentelemetry.javaagent.instrumentation.hibernate.v7_0.Value",
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
statelessSessionMethodTests.get(7)))),
|
||||||
|
Arguments.of(
|
||||||
|
named(
|
||||||
|
"update with entity name (StatelessSession)",
|
||||||
|
new Parameter(
|
||||||
|
"update",
|
||||||
|
"io.opentelemetry.javaagent.instrumentation.hibernate.v7_0.Value",
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
statelessSessionMethodTests.get(8)))),
|
||||||
|
Arguments.of(
|
||||||
|
named(
|
||||||
|
"delete (Session)",
|
||||||
|
new Parameter(
|
||||||
|
"delete",
|
||||||
|
"io.opentelemetry.javaagent.instrumentation.hibernate.v7_0.Value",
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
statelessSessionMethodTests.get(9)))),
|
||||||
|
Arguments.of(
|
||||||
|
named(
|
||||||
|
"delete with entity name (Session)",
|
||||||
|
new Parameter(
|
||||||
|
"delete",
|
||||||
|
"io.opentelemetry.javaagent.instrumentation.hibernate.v7_0.Value",
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
statelessSessionMethodTests.get(10)))));
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Stream<Arguments> provideHibernateReplicateParameters() {
|
||||||
|
List<BiConsumer<Session, Value>> sessionMethodTests =
|
||||||
|
Arrays.asList(
|
||||||
|
(session, val) -> {
|
||||||
|
Value replicated = new Value(val.getName() + " replicated");
|
||||||
|
replicated.setId(val.getId());
|
||||||
|
session.replicate(replicated, ReplicationMode.OVERWRITE);
|
||||||
|
},
|
||||||
|
(session, val) -> {
|
||||||
|
Value replicated = new Value(val.getName() + " replicated");
|
||||||
|
replicated.setId(val.getId());
|
||||||
|
session.replicate("Value", replicated, ReplicationMode.OVERWRITE);
|
||||||
|
});
|
||||||
|
|
||||||
|
return Stream.of(
|
||||||
|
Arguments.of(
|
||||||
|
named(
|
||||||
|
"replicate",
|
||||||
|
new Parameter(
|
||||||
|
"replicate",
|
||||||
|
"io.opentelemetry.javaagent.instrumentation.hibernate.v7_0.Value",
|
||||||
|
null,
|
||||||
|
sessionMethodTests.get(0),
|
||||||
|
null))),
|
||||||
|
Arguments.of(
|
||||||
|
named(
|
||||||
|
"replicate by entityName",
|
||||||
|
new Parameter("replicate", "Value", null, sessionMethodTests.get(1), null))));
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Stream<Arguments> provideHibernateCommitActionParameters() {
|
||||||
|
List<BiConsumer<Session, Value>> sessionMethodTests =
|
||||||
|
Arrays.asList(
|
||||||
|
(session, val) -> session.merge(new Value("merge me in")),
|
||||||
|
(session, val) -> session.merge("Value", new Value("merge me in")),
|
||||||
|
(session, val) -> session.persist(new Value("merge me in")),
|
||||||
|
(session, val) -> session.persist("Value", new Value("merge me in")),
|
||||||
|
(session, val) -> session.persist(null, new Value("merge me in")),
|
||||||
|
(session, val) -> {
|
||||||
|
session.remove(val);
|
||||||
|
prepopulated.remove(val);
|
||||||
|
});
|
||||||
|
|
||||||
|
return Stream.of(
|
||||||
|
Arguments.of(
|
||||||
|
named(
|
||||||
|
"merge",
|
||||||
|
new Parameter(
|
||||||
|
"merge",
|
||||||
|
"io.opentelemetry.javaagent.instrumentation.hibernate.v7_0.Value",
|
||||||
|
null,
|
||||||
|
sessionMethodTests.get(0),
|
||||||
|
null))),
|
||||||
|
Arguments.of(
|
||||||
|
named(
|
||||||
|
"merge with entity name",
|
||||||
|
new Parameter("merge", "Value", null, sessionMethodTests.get(1), null))),
|
||||||
|
Arguments.of(
|
||||||
|
named(
|
||||||
|
"persist",
|
||||||
|
new Parameter(
|
||||||
|
"persist",
|
||||||
|
"io.opentelemetry.javaagent.instrumentation.hibernate.v7_0.Value",
|
||||||
|
null,
|
||||||
|
sessionMethodTests.get(2),
|
||||||
|
null))),
|
||||||
|
Arguments.of(
|
||||||
|
named(
|
||||||
|
"persist with entity name",
|
||||||
|
new Parameter("persist", "Value", null, sessionMethodTests.get(3), null))),
|
||||||
|
Arguments.of(
|
||||||
|
named(
|
||||||
|
"persist with null entity name",
|
||||||
|
new Parameter(
|
||||||
|
"persist",
|
||||||
|
"io.opentelemetry.javaagent.instrumentation.hibernate.v7_0.Value",
|
||||||
|
null,
|
||||||
|
sessionMethodTests.get(4),
|
||||||
|
null))),
|
||||||
|
Arguments.of(
|
||||||
|
named(
|
||||||
|
"remove",
|
||||||
|
new Parameter(
|
||||||
|
"remove",
|
||||||
|
"io.opentelemetry.javaagent.instrumentation.hibernate.v7_0.Value",
|
||||||
|
null,
|
||||||
|
sessionMethodTests.get(5),
|
||||||
|
null))));
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Stream<Arguments> provideAttachesStateToQueryParameters() {
|
||||||
|
List<Function<Session, SelectionQuery<?>>> queryBuildMethods =
|
||||||
|
Arrays.asList(
|
||||||
|
session -> session.createQuery("from Value"),
|
||||||
|
session -> session.getNamedQuery("TestNamedQuery"),
|
||||||
|
session -> session.createNativeQuery("SELECT * FROM Value"),
|
||||||
|
session -> session.createSelectionQuery("from Value"));
|
||||||
|
|
||||||
|
return Stream.of(
|
||||||
|
Arguments.of(
|
||||||
|
named(
|
||||||
|
"createQuery",
|
||||||
|
new Parameter(
|
||||||
|
"createQuery",
|
||||||
|
"SELECT io.opentelemetry.javaagent.instrumentation.hibernate.v7_0.Value",
|
||||||
|
queryBuildMethods.get(0),
|
||||||
|
null,
|
||||||
|
null))),
|
||||||
|
Arguments.of(
|
||||||
|
named(
|
||||||
|
"getNamedQuery",
|
||||||
|
new Parameter(
|
||||||
|
"getNamedQuery",
|
||||||
|
"SELECT io.opentelemetry.javaagent.instrumentation.hibernate.v7_0.Value",
|
||||||
|
queryBuildMethods.get(1),
|
||||||
|
null,
|
||||||
|
null))),
|
||||||
|
Arguments.of(
|
||||||
|
named(
|
||||||
|
"createNativeQuery",
|
||||||
|
new Parameter(
|
||||||
|
"createNativeQuery", "SELECT Value", queryBuildMethods.get(2), null, null))),
|
||||||
|
Arguments.of(
|
||||||
|
named(
|
||||||
|
"createSelectionQuery",
|
||||||
|
new Parameter(
|
||||||
|
"createSelectionQuery",
|
||||||
|
"SELECT io.opentelemetry.javaagent.instrumentation.hibernate.v7_0.Value",
|
||||||
|
queryBuildMethods.get(3),
|
||||||
|
null,
|
||||||
|
null))));
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class Parameter {
|
||||||
|
Parameter(
|
||||||
|
String methodName,
|
||||||
|
String resource,
|
||||||
|
Function<Session, SelectionQuery<?>> queryBuildMethod,
|
||||||
|
BiConsumer<Session, Value> sessionMethodTest,
|
||||||
|
BiConsumer<StatelessSession, Value> statelessSessionMethodTest) {
|
||||||
|
this.methodName = methodName;
|
||||||
|
this.resource = resource;
|
||||||
|
this.sessionMethodTest = sessionMethodTest;
|
||||||
|
this.queryBuildMethod = queryBuildMethod;
|
||||||
|
this.statelessSessionMethodTest = statelessSessionMethodTest;
|
||||||
|
}
|
||||||
|
|
||||||
|
public final String methodName;
|
||||||
|
public final String resource;
|
||||||
|
public final Function<Session, SelectionQuery<?>> queryBuildMethod;
|
||||||
|
public final BiConsumer<Session, Value> sessionMethodTest;
|
||||||
|
public final BiConsumer<StatelessSession, Value> statelessSessionMethodTest;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static SpanDataAssert assertSessionSpan(
|
||||||
|
SpanDataAssert span, SpanData parent, String spanName) {
|
||||||
|
return span.hasName(spanName)
|
||||||
|
.hasKind(SpanKind.INTERNAL)
|
||||||
|
.hasParent(parent)
|
||||||
|
.hasAttributesSatisfyingExactly(
|
||||||
|
satisfies(
|
||||||
|
AttributeKey.stringKey("hibernate.session_id"),
|
||||||
|
val -> val.isInstanceOf(String.class)));
|
||||||
|
}
|
||||||
|
|
||||||
|
private static SpanDataAssert assertSpanWithSessionId(
|
||||||
|
SpanDataAssert span, SpanData parent, String spanName, String sessionId) {
|
||||||
|
return span.hasName(spanName)
|
||||||
|
.hasKind(SpanKind.INTERNAL)
|
||||||
|
.hasParent(parent)
|
||||||
|
.hasAttributesSatisfyingExactly(
|
||||||
|
equalTo(AttributeKey.stringKey("hibernate.session_id"), sessionId));
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("deprecation") // TODO DB_CONNECTION_STRING deprecation
|
||||||
|
private static SpanDataAssert assertClientSpan(SpanDataAssert span, SpanData parent) {
|
||||||
|
return span.hasKind(SpanKind.CLIENT)
|
||||||
|
.hasParent(parent)
|
||||||
|
.hasAttributesSatisfyingExactly(
|
||||||
|
equalTo(maybeStable(DB_SYSTEM), maybeStableDbSystemName("h2")),
|
||||||
|
equalTo(maybeStable(DB_NAME), "db1"),
|
||||||
|
equalTo(DB_USER, emitStableDatabaseSemconv() ? null : "sa"),
|
||||||
|
equalTo(DB_CONNECTION_STRING, emitStableDatabaseSemconv() ? null : "h2:mem:"),
|
||||||
|
satisfies(maybeStable(DB_STATEMENT), val -> val.isInstanceOf(String.class)),
|
||||||
|
satisfies(maybeStable(DB_OPERATION), val -> val.isInstanceOf(String.class)),
|
||||||
|
equalTo(maybeStable(DB_SQL_TABLE), "Value"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("deprecation") // TODO DB_CONNECTION_STRING deprecation
|
||||||
|
private static SpanDataAssert assertClientSpan(
|
||||||
|
SpanDataAssert span, SpanData parent, String verb) {
|
||||||
|
return span.hasName(verb.concat(" db1.Value"))
|
||||||
|
.hasKind(SpanKind.CLIENT)
|
||||||
|
.hasParent(parent)
|
||||||
|
.hasAttributesSatisfyingExactly(
|
||||||
|
equalTo(maybeStable(DB_SYSTEM), maybeStableDbSystemName("h2")),
|
||||||
|
equalTo(maybeStable(DB_NAME), "db1"),
|
||||||
|
equalTo(DB_USER, emitStableDatabaseSemconv() ? null : "sa"),
|
||||||
|
equalTo(DB_CONNECTION_STRING, emitStableDatabaseSemconv() ? null : "h2:mem:"),
|
||||||
|
satisfies(
|
||||||
|
maybeStable(DB_STATEMENT),
|
||||||
|
stringAssert -> stringAssert.startsWith(verb.toLowerCase(Locale.ROOT))),
|
||||||
|
equalTo(maybeStable(DB_OPERATION), verb),
|
||||||
|
equalTo(maybeStable(DB_SQL_TABLE), "Value"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,44 @@
|
||||||
|
/*
|
||||||
|
* Copyright The OpenTelemetry Authors
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
package io.opentelemetry.javaagent.instrumentation.hibernate.v7_0;
|
||||||
|
|
||||||
|
import jakarta.persistence.Entity;
|
||||||
|
import jakarta.persistence.Id;
|
||||||
|
import jakarta.persistence.Table;
|
||||||
|
import org.hibernate.annotations.NamedQuery;
|
||||||
|
|
||||||
|
@Entity
|
||||||
|
@Table
|
||||||
|
@NamedQuery(name = "TestNamedQuery", query = "from Value")
|
||||||
|
public class Value {
|
||||||
|
|
||||||
|
private Long id;
|
||||||
|
private String name;
|
||||||
|
|
||||||
|
public Value() {}
|
||||||
|
|
||||||
|
public Value(String name) {
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Id
|
||||||
|
@ValueGeneratedId
|
||||||
|
public Long getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setId(Long id) {
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setName(String title) {
|
||||||
|
name = title;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,19 @@
|
||||||
|
/*
|
||||||
|
* Copyright The OpenTelemetry Authors
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
package io.opentelemetry.javaagent.instrumentation.hibernate.v7_0;
|
||||||
|
|
||||||
|
import static java.lang.annotation.ElementType.FIELD;
|
||||||
|
import static java.lang.annotation.ElementType.METHOD;
|
||||||
|
|
||||||
|
import java.lang.annotation.Retention;
|
||||||
|
import java.lang.annotation.RetentionPolicy;
|
||||||
|
import java.lang.annotation.Target;
|
||||||
|
import org.hibernate.annotations.IdGeneratorType;
|
||||||
|
|
||||||
|
@IdGeneratorType(ValueIdGenerator.class)
|
||||||
|
@Target({FIELD, METHOD})
|
||||||
|
@Retention(RetentionPolicy.RUNTIME)
|
||||||
|
public @interface ValueGeneratedId {}
|
||||||
|
|
@ -0,0 +1,19 @@
|
||||||
|
/*
|
||||||
|
* Copyright The OpenTelemetry Authors
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
package io.opentelemetry.javaagent.instrumentation.hibernate.v7_0;
|
||||||
|
|
||||||
|
import java.util.concurrent.atomic.AtomicLong;
|
||||||
|
import org.hibernate.engine.spi.SharedSessionContractImplementor;
|
||||||
|
import org.hibernate.id.enhanced.SequenceStyleGenerator;
|
||||||
|
|
||||||
|
public class ValueIdGenerator extends SequenceStyleGenerator {
|
||||||
|
private final AtomicLong counter = new AtomicLong();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object generate(SharedSessionContractImplementor session, Object owner) {
|
||||||
|
return counter.incrementAndGet();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,29 @@
|
||||||
|
<?xml version='1.0' encoding='utf-8'?>
|
||||||
|
<!DOCTYPE hibernate-configuration PUBLIC
|
||||||
|
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
|
||||||
|
"http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
|
||||||
|
|
||||||
|
<hibernate-configuration>
|
||||||
|
|
||||||
|
<session-factory>
|
||||||
|
|
||||||
|
<!-- Use in-memory DB for testing -->
|
||||||
|
<property name="connection.driver_class">org.h2.Driver</property>
|
||||||
|
<property name="connection.url">jdbc:h2:mem:db1;DB_CLOSE_DELAY=-1;MVCC=TRUE</property>
|
||||||
|
<property name="connection.username">sa</property>
|
||||||
|
<property name="connection.password"/>
|
||||||
|
<property name="dialect">org.hibernate.dialect.H2Dialect</property>
|
||||||
|
|
||||||
|
<property name="connection.pool_size">3</property>
|
||||||
|
<property name="cache.provider_class">org.hibernate.cache.internal.NoCacheProvider</property>
|
||||||
|
<property name="show_sql">true</property>
|
||||||
|
|
||||||
|
<!-- Reset the DB each test -->
|
||||||
|
<property name="hbm2ddl.auto">create</property>
|
||||||
|
|
||||||
|
<!-- Objects -->
|
||||||
|
<mapping class="io.opentelemetry.javaagent.instrumentation.hibernate.v7_0.Value"/>
|
||||||
|
|
||||||
|
</session-factory>
|
||||||
|
|
||||||
|
</hibernate-configuration>
|
||||||
|
|
@ -0,0 +1,24 @@
|
||||||
|
<?xml version='1.0' encoding='utf-8'?>
|
||||||
|
<!DOCTYPE hibernate-configuration PUBLIC
|
||||||
|
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
|
||||||
|
"http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
|
||||||
|
|
||||||
|
<hibernate-configuration>
|
||||||
|
|
||||||
|
<session-factory>
|
||||||
|
|
||||||
|
<property name="hibernate.archive.autodetection">class,hbm</property>
|
||||||
|
<property name="hibernate.dialect">org.hibernate.dialect.HSQLDialect</property>
|
||||||
|
<property name="hibernate.show_sql">true</property>
|
||||||
|
<property name="hibernate.connection.driver_class">org.hsqldb.jdbcDriver</property>
|
||||||
|
<property name="hibernate.connection.username">sa</property>
|
||||||
|
<property name="hibernate.connection.password">1</property>
|
||||||
|
<property name="hibernate.connection.url">jdbc:hsqldb:mem:test</property>
|
||||||
|
<property name="hibernate.hbm2ddl.auto">create</property>
|
||||||
|
|
||||||
|
<!-- Objects -->
|
||||||
|
<mapping class="io.opentelemetry.javaagent.instrumentation.hibernate.v7_0.Value"/>
|
||||||
|
|
||||||
|
</session-factory>
|
||||||
|
|
||||||
|
</hibernate-configuration>
|
||||||
|
|
@ -64,7 +64,9 @@ public class SessionInstrumentation implements TypeInstrumentation {
|
||||||
"fireLock",
|
"fireLock",
|
||||||
"refresh",
|
"refresh",
|
||||||
"insert",
|
"insert",
|
||||||
"delete")),
|
"delete",
|
||||||
|
"remove",
|
||||||
|
"upsert")),
|
||||||
SessionInstrumentation.class.getName() + "$SessionMethodAdvice");
|
SessionInstrumentation.class.getName() + "$SessionMethodAdvice");
|
||||||
// Handle the non-generic 'get' separately.
|
// Handle the non-generic 'get' separately.
|
||||||
transformer.applyAdviceToMethod(
|
transformer.applyAdviceToMethod(
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,7 @@ import org.junit.jupiter.api.AfterAll;
|
||||||
import org.junit.jupiter.api.BeforeAll;
|
import org.junit.jupiter.api.BeforeAll;
|
||||||
import org.junit.jupiter.api.extension.RegisterExtension;
|
import org.junit.jupiter.api.extension.RegisterExtension;
|
||||||
|
|
||||||
public abstract class AbstractHibernateTest {
|
abstract class AbstractHibernateTest {
|
||||||
protected static SessionFactory sessionFactory;
|
protected static SessionFactory sessionFactory;
|
||||||
protected static List<Value> prepopulated;
|
protected static List<Value> prepopulated;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -34,7 +34,7 @@ import org.junit.jupiter.params.ParameterizedTest;
|
||||||
import org.junit.jupiter.params.provider.Arguments;
|
import org.junit.jupiter.params.provider.Arguments;
|
||||||
import org.junit.jupiter.params.provider.MethodSource;
|
import org.junit.jupiter.params.provider.MethodSource;
|
||||||
|
|
||||||
public class CriteriaTest extends AbstractHibernateTest {
|
class CriteriaTest extends AbstractHibernateTest {
|
||||||
private static Stream<Arguments> provideParameters() {
|
private static Stream<Arguments> provideParameters() {
|
||||||
List<Consumer<Query<Value>>> interactions =
|
List<Consumer<Query<Value>>> interactions =
|
||||||
Arrays.asList(Query::getResultList, Query::uniqueResult, Query::getSingleResultOrNull);
|
Arrays.asList(Query::getResultList, Query::uniqueResult, Query::getSingleResultOrNull);
|
||||||
|
|
|
||||||
|
|
@ -43,7 +43,7 @@ import org.junit.jupiter.params.ParameterizedTest;
|
||||||
import org.junit.jupiter.params.provider.Arguments;
|
import org.junit.jupiter.params.provider.Arguments;
|
||||||
import org.junit.jupiter.params.provider.MethodSource;
|
import org.junit.jupiter.params.provider.MethodSource;
|
||||||
|
|
||||||
public class EntityManagerTest extends AbstractHibernateTest {
|
class EntityManagerTest extends AbstractHibernateTest {
|
||||||
static final EntityManagerFactory entityManagerFactory =
|
static final EntityManagerFactory entityManagerFactory =
|
||||||
Persistence.createEntityManagerFactory("test-pu");
|
Persistence.createEntityManagerFactory("test-pu");
|
||||||
|
|
||||||
|
|
@ -258,7 +258,7 @@ public class EntityManagerTest extends AbstractHibernateTest {
|
||||||
named(
|
named(
|
||||||
"remove",
|
"remove",
|
||||||
new Parameter(
|
new Parameter(
|
||||||
"delete",
|
"remove",
|
||||||
"io.opentelemetry.javaagent.instrumentation.hibernate.v6_0.Value",
|
"io.opentelemetry.javaagent.instrumentation.hibernate.v6_0.Value",
|
||||||
true,
|
true,
|
||||||
true,
|
true,
|
||||||
|
|
|
||||||
|
|
@ -9,9 +9,12 @@ import jakarta.persistence.Entity;
|
||||||
import jakarta.persistence.GeneratedValue;
|
import jakarta.persistence.GeneratedValue;
|
||||||
import jakarta.persistence.Id;
|
import jakarta.persistence.Id;
|
||||||
import jakarta.persistence.Table;
|
import jakarta.persistence.Table;
|
||||||
import org.hibernate.annotations.GenericGenerator;
|
|
||||||
import org.hibernate.annotations.NamedQuery;
|
import org.hibernate.annotations.NamedQuery;
|
||||||
|
|
||||||
|
@SuppressWarnings({
|
||||||
|
"deprecation",
|
||||||
|
"removal"
|
||||||
|
}) // GenericGenerator is deprecated for removal in hibernate 7
|
||||||
@Entity
|
@Entity
|
||||||
@Table
|
@Table
|
||||||
@NamedQuery(name = "TestNamedQuery", query = "from Value")
|
@NamedQuery(name = "TestNamedQuery", query = "from Value")
|
||||||
|
|
@ -28,7 +31,7 @@ public class Value {
|
||||||
|
|
||||||
@Id
|
@Id
|
||||||
@GeneratedValue(generator = "increment")
|
@GeneratedValue(generator = "increment")
|
||||||
@GenericGenerator(name = "increment", strategy = "increment")
|
@org.hibernate.annotations.GenericGenerator(name = "increment", strategy = "increment")
|
||||||
public Long getId() {
|
public Long getId() {
|
||||||
return id;
|
return id;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -15,7 +15,7 @@ dependencies {
|
||||||
testInstrumentation(project(":instrumentation:hibernate:hibernate-procedure-call-4.3:javaagent"))
|
testInstrumentation(project(":instrumentation:hibernate:hibernate-procedure-call-4.3:javaagent"))
|
||||||
|
|
||||||
testImplementation("org.hsqldb:hsqldb:2.0.0")
|
testImplementation("org.hsqldb:hsqldb:2.0.0")
|
||||||
testImplementation("org.springframework.data:spring-data-jpa:3.0.0")
|
testLibrary("org.springframework.data:spring-data-jpa:3.0.0")
|
||||||
|
|
||||||
springAgent("org.springframework:spring-instrument:6.0.7")
|
springAgent("org.springframework:spring-instrument:6.0.7")
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -344,7 +344,7 @@ class SpringJpaTest {
|
||||||
stringKey("hibernate.session_id"),
|
stringKey("hibernate.session_id"),
|
||||||
val -> val.isInstanceOf(String.class))),
|
val -> val.isInstanceOf(String.class))),
|
||||||
span ->
|
span ->
|
||||||
span.hasName("Session.delete spring.jpa.Customer")
|
span.hasName("Session.remove spring.jpa.Customer")
|
||||||
.hasKind(INTERNAL)
|
.hasKind(INTERNAL)
|
||||||
.hasParent(trace.getSpan(0))
|
.hasParent(trace.getSpan(0))
|
||||||
.hasAttributesSatisfyingExactly(
|
.hasAttributesSatisfyingExactly(
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue