From 9db8582e2b443365a082ddd3eaa5232e5cd177cc Mon Sep 17 00:00:00 2001 From: Valentin Kovalenko Date: Wed, 12 Nov 2025 09:32:11 -0700 Subject: [PATCH 1/4] Make sure our extension does not interfere when bootstrapping unrelated to it HIBERNATE-135 --- build.gradle.kts | 1 + gradle/libs.versions.toml | 2 + ...=> ExceptionHandlingIntegrationTests.java} | 6 +- .../FailedBootstrappingIntegrationTests.java | 83 ------------------- ...sistenceBootstrappingIntegrationTests.java | 13 ++- .../NativeBootstrappingIntegrationTests.java | 57 +++++++++++++ ...stgreSQLBootstrappingIntegrationTests.java | 73 ++++++++++++++++ .../MongoAdditionalMappingContributor.java | 7 +- .../{extension => boot}/package-info.java | 2 +- .../StandardServiceRegistryScopedState.java | 5 +- .../{extension => }/service/package-info.java | 2 +- .../translate/AbstractMqlTranslator.java | 2 +- .../jdbc/MongoConnectionProvider.java | 4 +- ...nate.boot.spi.AdditionalMappingContributor | 6 +- ...g.hibernate.service.spi.ServiceContributor | 6 +- ...andardServiceRegistryScopedStateTests.java | 1 - ...lterTest.java => AstEmptyFilterTests.java} | 0 .../jdbc/MongoConnectionProviderTests.java | 2 +- 18 files changed, 167 insertions(+), 105 deletions(-) rename src/integrationTest/java/com/mongodb/hibernate/{ExceptionHandlingIntegrationTest.java => ExceptionHandlingIntegrationTests.java} (98%) delete mode 100644 src/integrationTest/java/com/mongodb/hibernate/boot/FailedBootstrappingIntegrationTests.java create mode 100644 src/integrationTest/java/com/mongodb/hibernate/boot/NativeBootstrappingIntegrationTests.java create mode 100644 src/integrationTest/java/com/mongodb/hibernate/boot/PostgreSQLBootstrappingIntegrationTests.java rename src/main/java/com/mongodb/hibernate/internal/{extension => boot}/MongoAdditionalMappingContributor.java (96%) rename src/main/java/com/mongodb/hibernate/internal/{extension => boot}/package-info.java (93%) rename src/main/java/com/mongodb/hibernate/internal/{extension => }/service/StandardServiceRegistryScopedState.java (96%) rename src/main/java/com/mongodb/hibernate/internal/{extension => }/service/package-info.java (93%) rename src/test/java/com/mongodb/hibernate/internal/translate/mongoast/filter/{AstEmptyFilterTest.java => AstEmptyFilterTests.java} (100%) diff --git a/build.gradle.kts b/build.gradle.kts index 2c179807..92292749 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -177,6 +177,7 @@ dependencies { exclude(group = "org.apache.logging.log4j", module = "log4j-core") } integrationTestRuntimeOnly("org.junit.platform:junit-platform-launcher") + integrationTestRuntimeOnly(libs.postgresql) api(libs.jspecify) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 54fc15b6..68315bd2 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -25,6 +25,7 @@ slf4j-api = "2.0.16" logback-classic = "1.5.16" mockito = "5.16.0" checker-qual = "3.49.1" +postgresql = "42.7.8" plugin-spotless = "7.0.2" plugin-errorprone = "4.1.0" @@ -47,6 +48,7 @@ sl4j-api = { module = "org.slf4j:slf4j-api", version.ref = "slf4j-api" } logback-classic = { module = "ch.qos.logback:logback-classic", version.ref = "logback-classic" } mockito-junit-jupiter = { module = "org.mockito:mockito-junit-jupiter", version.ref = "mockito" } checker-qual = { module = "org.checkerframework:checker-qual", version.ref = "checker-qual" } +postgresql = { module = "org.postgresql:postgresql", version.ref = "postgresql" } [bundles] test-common = ["junit-jupiter", "assertj", "logback-classic"] diff --git a/src/integrationTest/java/com/mongodb/hibernate/ExceptionHandlingIntegrationTest.java b/src/integrationTest/java/com/mongodb/hibernate/ExceptionHandlingIntegrationTests.java similarity index 98% rename from src/integrationTest/java/com/mongodb/hibernate/ExceptionHandlingIntegrationTest.java rename to src/integrationTest/java/com/mongodb/hibernate/ExceptionHandlingIntegrationTests.java index 9307aedb..313de6fe 100644 --- a/src/integrationTest/java/com/mongodb/hibernate/ExceptionHandlingIntegrationTest.java +++ b/src/integrationTest/java/com/mongodb/hibernate/ExceptionHandlingIntegrationTests.java @@ -46,9 +46,9 @@ /** @see MongoDialect#buildSQLExceptionConversionDelegate() */ @SessionFactory(exportSchema = false) -@DomainModel(annotatedClasses = {ExceptionHandlingIntegrationTest.Item.class}) +@DomainModel(annotatedClasses = {ExceptionHandlingIntegrationTests.Item.class}) @ExtendWith(MongoExtension.class) -class ExceptionHandlingIntegrationTest implements SessionFactoryScopeAware { +class ExceptionHandlingIntegrationTests implements SessionFactoryScopeAware { private static final String COLLECTION_NAME = "items"; private static final String EXCEPTION_MESSAGE_FAILED_TO_EXECUTE_OPERATION = "Failed to execute operation"; private static final String EXCEPTION_MESSAGE_TIMEOUT = "Timeout while waiting for operation to complete"; @@ -101,7 +101,7 @@ void testTimeoutExceptionThrown() { @ServiceRegistry(settings = @Setting(name = AvailableSettings.STATEMENT_BATCH_SIZE, value = "2")) @ExtendWith(MongoExtension.class) @SessionFactory(exportSchema = false) - @DomainModel(annotatedClasses = {ExceptionHandlingIntegrationTest.Item.class}) + @DomainModel(annotatedClasses = {ExceptionHandlingIntegrationTests.Item.class}) class Batch implements SessionFactoryScopeAware { SessionFactoryScope sessionFactoryScope; diff --git a/src/integrationTest/java/com/mongodb/hibernate/boot/FailedBootstrappingIntegrationTests.java b/src/integrationTest/java/com/mongodb/hibernate/boot/FailedBootstrappingIntegrationTests.java deleted file mode 100644 index 72eab997..00000000 --- a/src/integrationTest/java/com/mongodb/hibernate/boot/FailedBootstrappingIntegrationTests.java +++ /dev/null @@ -1,83 +0,0 @@ -/* - * Copyright 2024-present MongoDB, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.mongodb.hibernate.boot; - -import static org.assertj.core.api.Assertions.assertThatThrownBy; - -import com.mongodb.client.MongoClient; -import com.mongodb.hibernate.junit.InjectMongoClient; -import com.mongodb.hibernate.junit.MongoExtension; -import org.bson.BsonDocument; -import org.bson.BsonString; -import org.hibernate.boot.MetadataSources; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; - -@ExtendWith(MongoExtension.class) -class FailedBootstrappingIntegrationTests { - @InjectMongoClient - private static MongoClient mongoClient; - - @Test - @SuppressWarnings("try") - void couldNotInstantiateDialect() { - assertThatThrownBy(() -> { - try (var failPoint = FailPoint.enable( - BsonDocument.parse( - """ - { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 - }, - "data": { - "failCommands": ["buildInfo"], - "errorCode": 1 - } - } - """))) { - new MetadataSources().buildMetadata(); - } - }) - .hasRootCause( - new RuntimeException( - "Could not instantiate [com.mongodb.hibernate.dialect.MongoDialect], see the earlier exceptions to find out why")); - } - - static final class FailPoint implements AutoCloseable { - private final BsonDocument failPointDocument; - - private FailPoint(BsonDocument failPointDocument) { - this.failPointDocument = failPointDocument; - } - - static FailPoint enable(BsonDocument configureFailPointDoc) { - var result = new FailPoint(configureFailPointDoc); - mongoClient.getDatabase("admin").runCommand(configureFailPointDoc); - return result; - } - - @Override - public void close() { - mongoClient - .getDatabase("admin") - .runCommand(new BsonDocument() - .append("configureFailPoint", failPointDocument.getString("configureFailPoint")) - .append("mode", new BsonString("off"))); - } - } -} diff --git a/src/integrationTest/java/com/mongodb/hibernate/boot/JakartaPersistenceBootstrappingIntegrationTests.java b/src/integrationTest/java/com/mongodb/hibernate/boot/JakartaPersistenceBootstrappingIntegrationTests.java index 74116584..2802c8b5 100644 --- a/src/integrationTest/java/com/mongodb/hibernate/boot/JakartaPersistenceBootstrappingIntegrationTests.java +++ b/src/integrationTest/java/com/mongodb/hibernate/boot/JakartaPersistenceBootstrappingIntegrationTests.java @@ -16,6 +16,7 @@ package com.mongodb.hibernate.boot; +import static com.mongodb.hibernate.BasicCrudIntegrationTests.Item.COLLECTION_NAME; import static org.assertj.core.api.Assertions.assertThat; import com.mongodb.client.MongoCollection; @@ -41,18 +42,12 @@ annotatedClasses = JakartaPersistenceBootstrappingIntegrationTests.Item.class) @ExtendWith(MongoExtension.class) class JakartaPersistenceBootstrappingIntegrationTests { - private static final String COLLECTION_NAME = "items"; - @InjectMongoCollection(COLLECTION_NAME) private static MongoCollection mongoCollection; @Test void smoke(EntityManagerFactoryScope scope) { - scope.inTransaction(em -> { - var item = new Item(); - item.id = 1; - em.persist(item); - }); + scope.inTransaction(em -> em.persist(new Item(1))); assertThat(mongoCollection.find()).containsExactly(BsonDocument.parse("{_id: 1}")); } @@ -61,5 +56,9 @@ void smoke(EntityManagerFactoryScope scope) { static class Item { @Id int id; + + Item(int id) { + this.id = id; + } } } diff --git a/src/integrationTest/java/com/mongodb/hibernate/boot/NativeBootstrappingIntegrationTests.java b/src/integrationTest/java/com/mongodb/hibernate/boot/NativeBootstrappingIntegrationTests.java new file mode 100644 index 00000000..62ce2c9e --- /dev/null +++ b/src/integrationTest/java/com/mongodb/hibernate/boot/NativeBootstrappingIntegrationTests.java @@ -0,0 +1,57 @@ +/* + * Copyright 2024-present MongoDB, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.mongodb.hibernate.boot; + +import static org.assertj.core.api.Assertions.assertThatThrownBy; + +import com.mongodb.client.MongoClient; +import com.mongodb.hibernate.junit.InjectMongoClient; +import com.mongodb.hibernate.junit.MongoExtension; +import org.bson.BsonDocument; +import org.hibernate.boot.MetadataSources; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; + +@ExtendWith(MongoExtension.class) +class NativeBootstrappingIntegrationTests { + @InjectMongoClient + private static MongoClient mongoClient; + + @Test + @SuppressWarnings("try") + void testCouldNotInstantiateDialectExceptionMessage() { + assertThatThrownBy(() -> { + BsonDocument failPointCommand = BsonDocument.parse( + """ + { + "configureFailPoint": "failCommand", + "mode": { + "times": 1 + }, + "data": { + "failCommands": ["buildInfo"], + "errorCode": 1 + } + } + """); + mongoClient.getDatabase("admin").runCommand(failPointCommand); + new MetadataSources().buildMetadata(); + }) + .hasRootCauseMessage( + "Could not instantiate [com.mongodb.hibernate.dialect.MongoDialect], see the earlier exceptions to find out why"); + } +} diff --git a/src/integrationTest/java/com/mongodb/hibernate/boot/PostgreSQLBootstrappingIntegrationTests.java b/src/integrationTest/java/com/mongodb/hibernate/boot/PostgreSQLBootstrappingIntegrationTests.java new file mode 100644 index 00000000..bf916558 --- /dev/null +++ b/src/integrationTest/java/com/mongodb/hibernate/boot/PostgreSQLBootstrappingIntegrationTests.java @@ -0,0 +1,73 @@ +/* + * Copyright 2025-present MongoDB, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.mongodb.hibernate.boot; + +import static com.mongodb.hibernate.BasicCrudIntegrationTests.Item.COLLECTION_NAME; +import static org.assertj.core.api.Assertions.assertThatThrownBy; + +import com.mongodb.hibernate.internal.boot.MongoAdditionalMappingContributor; +import com.mongodb.hibernate.junit.MongoExtension; +import jakarta.persistence.Embeddable; +import jakarta.persistence.Entity; +import jakarta.persistence.Id; +import jakarta.persistence.Table; +import org.hibernate.InstantiationException; +import org.hibernate.cfg.AvailableSettings; +import org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl; +import org.hibernate.testing.orm.junit.EntityManagerFactoryScope; +import org.hibernate.testing.orm.junit.Jpa; +import org.hibernate.testing.orm.junit.Setting; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; + +@Jpa( + exportSchema = false, + integrationSettings = { + @Setting(name = AvailableSettings.DIALECT, value = "org.hibernate.dialect.PostgreSQLDialect"), + @Setting(name = AvailableSettings.JAKARTA_JDBC_URL, value = "postgresql://"), + @Setting(name = AvailableSettings.JAKARTA_JDBC_DRIVER, value = "org.postgresql.Driver"), + @Setting(name = DriverManagerConnectionProviderImpl.INITIAL_SIZE, value = "0"), + }, + annotatedClasses = PostgreSQLBootstrappingIntegrationTests.Item.class) +@ExtendWith(MongoExtension.class) +class PostgreSQLBootstrappingIntegrationTests { + /** + * Verify that {@link MongoAdditionalMappingContributor} skips its logic when bootstrapping is unrelated to the + * MongoDB Extension for Hibernate ORM. + */ + @Test + void testMongoAdditionalMappingContributorIsSkipped(EntityManagerFactoryScope scope) { + assertThatThrownBy(() -> scope.inTransaction(em -> em.persist(new Item(null)))) + .hasMessageNotContaining("does not support primary key spanning multiple columns") + .isInstanceOf(InstantiationException.class) + .hasMessageMatching("Could not instantiate entity .* due to: null"); + } + + @Entity + @Table(name = COLLECTION_NAME) + static class Item { + @Id + MultipleColumns id; + + Item(MultipleColumns id) { + this.id = id; + } + } + + @Embeddable + record MultipleColumns(int a, int b) {} +} diff --git a/src/main/java/com/mongodb/hibernate/internal/extension/MongoAdditionalMappingContributor.java b/src/main/java/com/mongodb/hibernate/internal/boot/MongoAdditionalMappingContributor.java similarity index 96% rename from src/main/java/com/mongodb/hibernate/internal/extension/MongoAdditionalMappingContributor.java rename to src/main/java/com/mongodb/hibernate/internal/boot/MongoAdditionalMappingContributor.java index 1d475b6b..6c9f2e86 100644 --- a/src/main/java/com/mongodb/hibernate/internal/extension/MongoAdditionalMappingContributor.java +++ b/src/main/java/com/mongodb/hibernate/internal/boot/MongoAdditionalMappingContributor.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.mongodb.hibernate.internal.extension; +package com.mongodb.hibernate.internal.boot; import static com.mongodb.hibernate.internal.MongoAssertions.assertFalse; import static com.mongodb.hibernate.internal.MongoAssertions.assertInstanceOf; @@ -23,6 +23,7 @@ import static com.mongodb.hibernate.internal.MongoConstants.MONGO_DBMS_NAME; import static java.lang.String.format; +import com.mongodb.hibernate.dialect.MongoDialect; import com.mongodb.hibernate.internal.FeatureNotSupportedException; import jakarta.persistence.Embeddable; import java.sql.Time; @@ -83,6 +84,10 @@ public void contribute( InFlightMetadataCollector metadata, ResourceStreamLocator resourceStreamLocator, MetadataBuildingContext buildingContext) { + if (!(metadata.getDatabase().getDialect() instanceof MongoDialect)) { + // avoid interfering with bootstrapping unrelated to the MongoDB Extension for Hibernate ORM + return; + } forbidEmbeddablesWithoutPersistentAttributes(metadata); metadata.getEntityBindings().forEach(persistentClass -> { checkPropertyTypes(persistentClass); diff --git a/src/main/java/com/mongodb/hibernate/internal/extension/package-info.java b/src/main/java/com/mongodb/hibernate/internal/boot/package-info.java similarity index 93% rename from src/main/java/com/mongodb/hibernate/internal/extension/package-info.java rename to src/main/java/com/mongodb/hibernate/internal/boot/package-info.java index 3501bb2a..4f00b041 100644 --- a/src/main/java/com/mongodb/hibernate/internal/extension/package-info.java +++ b/src/main/java/com/mongodb/hibernate/internal/boot/package-info.java @@ -16,6 +16,6 @@ /** The program elements within this package are not part of the public API and may be removed or changed at any time */ @NullMarked -package com.mongodb.hibernate.internal.extension; +package com.mongodb.hibernate.internal.boot; import org.jspecify.annotations.NullMarked; diff --git a/src/main/java/com/mongodb/hibernate/internal/extension/service/StandardServiceRegistryScopedState.java b/src/main/java/com/mongodb/hibernate/internal/service/StandardServiceRegistryScopedState.java similarity index 96% rename from src/main/java/com/mongodb/hibernate/internal/extension/service/StandardServiceRegistryScopedState.java rename to src/main/java/com/mongodb/hibernate/internal/service/StandardServiceRegistryScopedState.java index 01d0adf0..528295f0 100644 --- a/src/main/java/com/mongodb/hibernate/internal/extension/service/StandardServiceRegistryScopedState.java +++ b/src/main/java/com/mongodb/hibernate/internal/service/StandardServiceRegistryScopedState.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.mongodb.hibernate.internal.extension.service; +package com.mongodb.hibernate.internal.service; import static com.mongodb.hibernate.internal.VisibleForTesting.AccessModifier.PRIVATE; import static java.lang.String.format; @@ -84,8 +84,7 @@ public StandardServiceRegistryScopedState initiateService( private MongoConfiguration createMongoConfiguration( Map configurationValues, ServiceRegistryImplementor serviceRegistry) { var jdbcUrl = configurationValues.get(JAKARTA_JDBC_URL); - MongoConfigurationContributor mongoConfigurationContributor = - getMongoConfigurationContributor(serviceRegistry); + var mongoConfigurationContributor = getMongoConfigurationContributor(serviceRegistry); if (jdbcUrl == null && mongoConfigurationContributor == null) { throw new HibernateException(format( "Configuration property [%s] is required unless %s is provided", diff --git a/src/main/java/com/mongodb/hibernate/internal/extension/service/package-info.java b/src/main/java/com/mongodb/hibernate/internal/service/package-info.java similarity index 93% rename from src/main/java/com/mongodb/hibernate/internal/extension/service/package-info.java rename to src/main/java/com/mongodb/hibernate/internal/service/package-info.java index ea4a3cb1..929a6a6c 100644 --- a/src/main/java/com/mongodb/hibernate/internal/extension/service/package-info.java +++ b/src/main/java/com/mongodb/hibernate/internal/service/package-info.java @@ -16,6 +16,6 @@ /** The program elements within this package are not part of the public API and may be removed or changed at any time */ @NullMarked -package com.mongodb.hibernate.internal.extension.service; +package com.mongodb.hibernate.internal.service; import org.jspecify.annotations.NullMarked; diff --git a/src/main/java/com/mongodb/hibernate/internal/translate/AbstractMqlTranslator.java b/src/main/java/com/mongodb/hibernate/internal/translate/AbstractMqlTranslator.java index 6bfb898d..4395f1ef 100644 --- a/src/main/java/com/mongodb/hibernate/internal/translate/AbstractMqlTranslator.java +++ b/src/main/java/com/mongodb/hibernate/internal/translate/AbstractMqlTranslator.java @@ -51,7 +51,7 @@ import static org.hibernate.query.sqm.FetchClauseType.ROWS_ONLY; import com.mongodb.hibernate.internal.FeatureNotSupportedException; -import com.mongodb.hibernate.internal.extension.service.StandardServiceRegistryScopedState; +import com.mongodb.hibernate.internal.service.StandardServiceRegistryScopedState; import com.mongodb.hibernate.internal.translate.mongoast.AstDocument; import com.mongodb.hibernate.internal.translate.mongoast.AstElement; import com.mongodb.hibernate.internal.translate.mongoast.AstFieldUpdate; diff --git a/src/main/java/com/mongodb/hibernate/jdbc/MongoConnectionProvider.java b/src/main/java/com/mongodb/hibernate/jdbc/MongoConnectionProvider.java index e7162723..c532903c 100644 --- a/src/main/java/com/mongodb/hibernate/jdbc/MongoConnectionProvider.java +++ b/src/main/java/com/mongodb/hibernate/jdbc/MongoConnectionProvider.java @@ -25,7 +25,7 @@ import com.mongodb.client.MongoClients; import com.mongodb.hibernate.internal.BuildConfig; import com.mongodb.hibernate.internal.VisibleForTesting; -import com.mongodb.hibernate.internal.extension.service.StandardServiceRegistryScopedState; +import com.mongodb.hibernate.internal.service.StandardServiceRegistryScopedState; import java.io.IOException; import java.io.NotSerializableException; import java.io.ObjectOutputStream; @@ -58,6 +58,8 @@ public final class MongoConnectionProvider implements ConnectionProvider, Stoppa private @Nullable StandardServiceRegistryScopedState standardServiceRegistryScopedState; private transient @Nullable MongoClient mongoClient; + public MongoConnectionProvider() {} + @Override public Connection getConnection() throws SQLException { try { diff --git a/src/main/resources/META-INF/services/org.hibernate.boot.spi.AdditionalMappingContributor b/src/main/resources/META-INF/services/org.hibernate.boot.spi.AdditionalMappingContributor index 842d5ddb..d3000e83 100644 --- a/src/main/resources/META-INF/services/org.hibernate.boot.spi.AdditionalMappingContributor +++ b/src/main/resources/META-INF/services/org.hibernate.boot.spi.AdditionalMappingContributor @@ -1 +1,5 @@ -com.mongodb.hibernate.internal.extension.MongoAdditionalMappingContributor \ No newline at end of file +# Hibernate ORM runs additional mapping contributors for any +# `org.hibernate.SessionFactory`/`jakarta.persistence.EntityManagerFactory` that is being bootstrapped. +# Consequently, this contributor must check that the involved dialect is `com.mongodb.hibernate.dialect.MongoDialect`, +# to avoid interfering with bootstrapping unrelated to the MongoDB Extension for Hibernate ORM. +com.mongodb.hibernate.internal.boot.MongoAdditionalMappingContributor \ No newline at end of file diff --git a/src/main/resources/META-INF/services/org.hibernate.service.spi.ServiceContributor b/src/main/resources/META-INF/services/org.hibernate.service.spi.ServiceContributor index 3f3d12fc..6c163955 100644 --- a/src/main/resources/META-INF/services/org.hibernate.service.spi.ServiceContributor +++ b/src/main/resources/META-INF/services/org.hibernate.service.spi.ServiceContributor @@ -1 +1,5 @@ -com.mongodb.hibernate.internal.extension.service.StandardServiceRegistryScopedState$ServiceContributor +# Hibernate ORM initiates services on demand, so despite this service contributor being available to any +# `org.hibernate.SessionFactory`/`jakarta.persistence.EntityManagerFactory` that is being bootstrapped, +# its corresponding service will not be initiated until it is requested. +# That means, it will not interfere with bootstrapping unrelated to the MongoDB Extension for Hibernate ORM. +com.mongodb.hibernate.internal.service.StandardServiceRegistryScopedState$ServiceContributor diff --git a/src/test/java/com/mongodb/hibernate/internal/service/StandardServiceRegistryScopedStateTests.java b/src/test/java/com/mongodb/hibernate/internal/service/StandardServiceRegistryScopedStateTests.java index ecf2d6b5..22e38af2 100644 --- a/src/test/java/com/mongodb/hibernate/internal/service/StandardServiceRegistryScopedStateTests.java +++ b/src/test/java/com/mongodb/hibernate/internal/service/StandardServiceRegistryScopedStateTests.java @@ -19,7 +19,6 @@ import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNotSame; -import com.mongodb.hibernate.internal.extension.service.StandardServiceRegistryScopedState; import com.mongodb.hibernate.service.spi.MongoConfigurationContributor; import java.util.ArrayList; import org.hibernate.boot.MetadataSources; diff --git a/src/test/java/com/mongodb/hibernate/internal/translate/mongoast/filter/AstEmptyFilterTest.java b/src/test/java/com/mongodb/hibernate/internal/translate/mongoast/filter/AstEmptyFilterTests.java similarity index 100% rename from src/test/java/com/mongodb/hibernate/internal/translate/mongoast/filter/AstEmptyFilterTest.java rename to src/test/java/com/mongodb/hibernate/internal/translate/mongoast/filter/AstEmptyFilterTests.java diff --git a/src/test/java/com/mongodb/hibernate/jdbc/MongoConnectionProviderTests.java b/src/test/java/com/mongodb/hibernate/jdbc/MongoConnectionProviderTests.java index 7b5624a1..c0da5bc1 100644 --- a/src/test/java/com/mongodb/hibernate/jdbc/MongoConnectionProviderTests.java +++ b/src/test/java/com/mongodb/hibernate/jdbc/MongoConnectionProviderTests.java @@ -24,7 +24,7 @@ import com.mongodb.client.internal.MongoClientImpl; import com.mongodb.hibernate.internal.BuildConfig; import com.mongodb.hibernate.internal.cfg.MongoConfiguration; -import com.mongodb.hibernate.internal.extension.service.StandardServiceRegistryScopedState; +import com.mongodb.hibernate.internal.service.StandardServiceRegistryScopedState; import java.sql.SQLException; import org.junit.jupiter.api.AutoClose; import org.junit.jupiter.api.BeforeEach; From 9d11a0be8d6ed8365d6bc863def87f82ab6f7f97 Mon Sep 17 00:00:00 2001 From: Valentin Kovalenko Date: Wed, 19 Nov 2025 01:11:08 -0700 Subject: [PATCH 2/4] Remove unnecessary `@SuppressWarnings("try")` HIBERNATE-135 --- .../hibernate/boot/NativeBootstrappingIntegrationTests.java | 1 - 1 file changed, 1 deletion(-) diff --git a/src/integrationTest/java/com/mongodb/hibernate/boot/NativeBootstrappingIntegrationTests.java b/src/integrationTest/java/com/mongodb/hibernate/boot/NativeBootstrappingIntegrationTests.java index 62ce2c9e..b1cd8918 100644 --- a/src/integrationTest/java/com/mongodb/hibernate/boot/NativeBootstrappingIntegrationTests.java +++ b/src/integrationTest/java/com/mongodb/hibernate/boot/NativeBootstrappingIntegrationTests.java @@ -32,7 +32,6 @@ class NativeBootstrappingIntegrationTests { private static MongoClient mongoClient; @Test - @SuppressWarnings("try") void testCouldNotInstantiateDialectExceptionMessage() { assertThatThrownBy(() -> { BsonDocument failPointCommand = BsonDocument.parse( From f7dbe5867d930475951e53b51e774486be5353f5 Mon Sep 17 00:00:00 2001 From: Valentin Kovalenko Date: Fri, 21 Nov 2025 16:36:23 -0700 Subject: [PATCH 3/4] Throw meaningful exceptions if either our dialect or connection provider is not plugged in HIBERNATE-135 --- build.gradle.kts | 1 - gradle/libs.versions.toml | 2 - .../SessionFactoryIntegrationTests.java | 18 ++-- ...stgreSQLBootstrappingIntegrationTests.java | 73 --------------- .../StandardServiceRegistryScopedState.java | 44 ++++++++- .../boot/NativeBootstrappingTests.java | 89 +++++++++++++++++++ ...andardServiceRegistryScopedStateTests.java | 26 ++++++ .../MongoConfigurationContributorTests.java | 8 +- 8 files changed, 168 insertions(+), 93 deletions(-) delete mode 100644 src/integrationTest/java/com/mongodb/hibernate/boot/PostgreSQLBootstrappingIntegrationTests.java create mode 100644 src/test/java/com/mongodb/hibernate/boot/NativeBootstrappingTests.java diff --git a/build.gradle.kts b/build.gradle.kts index 92292749..2c179807 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -177,7 +177,6 @@ dependencies { exclude(group = "org.apache.logging.log4j", module = "log4j-core") } integrationTestRuntimeOnly("org.junit.platform:junit-platform-launcher") - integrationTestRuntimeOnly(libs.postgresql) api(libs.jspecify) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 68315bd2..54fc15b6 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -25,7 +25,6 @@ slf4j-api = "2.0.16" logback-classic = "1.5.16" mockito = "5.16.0" checker-qual = "3.49.1" -postgresql = "42.7.8" plugin-spotless = "7.0.2" plugin-errorprone = "4.1.0" @@ -48,7 +47,6 @@ sl4j-api = { module = "org.slf4j:slf4j-api", version.ref = "slf4j-api" } logback-classic = { module = "ch.qos.logback:logback-classic", version.ref = "logback-classic" } mockito-junit-jupiter = { module = "org.mockito:mockito-junit-jupiter", version.ref = "mockito" } checker-qual = { module = "org.checkerframework:checker-qual", version.ref = "checker-qual" } -postgresql = { module = "org.postgresql:postgresql", version.ref = "postgresql" } [bundles] test-common = ["junit-jupiter", "assertj", "logback-classic"] diff --git a/src/integrationTest/java/com/mongodb/hibernate/SessionFactoryIntegrationTests.java b/src/integrationTest/java/com/mongodb/hibernate/SessionFactoryIntegrationTests.java index b19931fb..caa4db78 100644 --- a/src/integrationTest/java/com/mongodb/hibernate/SessionFactoryIntegrationTests.java +++ b/src/integrationTest/java/com/mongodb/hibernate/SessionFactoryIntegrationTests.java @@ -36,9 +36,9 @@ void testSuccess() { @Test void testInvalidConnectionString() { - assertThrows(ServiceException.class, () -> buildSessionFactory( - Map.of(JAKARTA_JDBC_URL, "jdbc:postgresql://localhost/test")) - .close()); + assertThrows( + ServiceException.class, () -> buildSessionFactory(Map.of(JAKARTA_JDBC_URL, "jdbc:postgresql://host/")) + .close()); } @Test @@ -60,12 +60,10 @@ private static SessionFactory buildSessionFactory() throws ServiceException { } private static SessionFactory buildSessionFactory(Map settings) throws ServiceException { - var standardServiceRegistry = - new StandardServiceRegistryBuilder().applySettings(settings).build(); - return new MetadataSources(standardServiceRegistry) - .getMetadataBuilder() - .build() - .getSessionFactoryBuilder() - .build(); + return new MetadataSources() + .buildMetadata(new StandardServiceRegistryBuilder() + .applySettings(settings) + .build()) + .buildSessionFactory(); } } diff --git a/src/integrationTest/java/com/mongodb/hibernate/boot/PostgreSQLBootstrappingIntegrationTests.java b/src/integrationTest/java/com/mongodb/hibernate/boot/PostgreSQLBootstrappingIntegrationTests.java deleted file mode 100644 index bf916558..00000000 --- a/src/integrationTest/java/com/mongodb/hibernate/boot/PostgreSQLBootstrappingIntegrationTests.java +++ /dev/null @@ -1,73 +0,0 @@ -/* - * Copyright 2025-present MongoDB, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.mongodb.hibernate.boot; - -import static com.mongodb.hibernate.BasicCrudIntegrationTests.Item.COLLECTION_NAME; -import static org.assertj.core.api.Assertions.assertThatThrownBy; - -import com.mongodb.hibernate.internal.boot.MongoAdditionalMappingContributor; -import com.mongodb.hibernate.junit.MongoExtension; -import jakarta.persistence.Embeddable; -import jakarta.persistence.Entity; -import jakarta.persistence.Id; -import jakarta.persistence.Table; -import org.hibernate.InstantiationException; -import org.hibernate.cfg.AvailableSettings; -import org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl; -import org.hibernate.testing.orm.junit.EntityManagerFactoryScope; -import org.hibernate.testing.orm.junit.Jpa; -import org.hibernate.testing.orm.junit.Setting; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; - -@Jpa( - exportSchema = false, - integrationSettings = { - @Setting(name = AvailableSettings.DIALECT, value = "org.hibernate.dialect.PostgreSQLDialect"), - @Setting(name = AvailableSettings.JAKARTA_JDBC_URL, value = "postgresql://"), - @Setting(name = AvailableSettings.JAKARTA_JDBC_DRIVER, value = "org.postgresql.Driver"), - @Setting(name = DriverManagerConnectionProviderImpl.INITIAL_SIZE, value = "0"), - }, - annotatedClasses = PostgreSQLBootstrappingIntegrationTests.Item.class) -@ExtendWith(MongoExtension.class) -class PostgreSQLBootstrappingIntegrationTests { - /** - * Verify that {@link MongoAdditionalMappingContributor} skips its logic when bootstrapping is unrelated to the - * MongoDB Extension for Hibernate ORM. - */ - @Test - void testMongoAdditionalMappingContributorIsSkipped(EntityManagerFactoryScope scope) { - assertThatThrownBy(() -> scope.inTransaction(em -> em.persist(new Item(null)))) - .hasMessageNotContaining("does not support primary key spanning multiple columns") - .isInstanceOf(InstantiationException.class) - .hasMessageMatching("Could not instantiate entity .* due to: null"); - } - - @Entity - @Table(name = COLLECTION_NAME) - static class Item { - @Id - MultipleColumns id; - - Item(MultipleColumns id) { - this.id = id; - } - } - - @Embeddable - record MultipleColumns(int a, int b) {} -} diff --git a/src/main/java/com/mongodb/hibernate/internal/service/StandardServiceRegistryScopedState.java b/src/main/java/com/mongodb/hibernate/internal/service/StandardServiceRegistryScopedState.java index 528295f0..5a274439 100644 --- a/src/main/java/com/mongodb/hibernate/internal/service/StandardServiceRegistryScopedState.java +++ b/src/main/java/com/mongodb/hibernate/internal/service/StandardServiceRegistryScopedState.java @@ -22,9 +22,11 @@ import static org.hibernate.cfg.AvailableSettings.JAVA_TIME_USE_DIRECT_JDBC; import static org.hibernate.cfg.AvailableSettings.PREFERRED_INSTANT_JDBC_TYPE; +import com.mongodb.hibernate.dialect.MongoDialect; import com.mongodb.hibernate.internal.VisibleForTesting; import com.mongodb.hibernate.internal.cfg.MongoConfiguration; import com.mongodb.hibernate.internal.cfg.MongoConfigurationBuilder; +import com.mongodb.hibernate.jdbc.MongoConnectionProvider; import com.mongodb.hibernate.service.spi.MongoConfigurationContributor; import java.io.IOException; import java.io.NotSerializableException; @@ -35,6 +37,8 @@ import org.hibernate.HibernateException; import org.hibernate.boot.registry.StandardServiceInitiator; import org.hibernate.boot.registry.StandardServiceRegistryBuilder; +import org.hibernate.cfg.AvailableSettings; +import org.hibernate.engine.jdbc.dialect.spi.DialectFactory; import org.hibernate.service.Service; import org.hibernate.service.UnknownServiceException; import org.hibernate.service.spi.ServiceRegistryImplementor; @@ -75,13 +79,49 @@ public Class getServiceInitiated() { @Override public StandardServiceRegistryScopedState initiateService( Map configurationValues, ServiceRegistryImplementor serviceRegistry) { + checkMongoDialectIsPluggedIn(configurationValues, serviceRegistry); + checkMongoConnectionProviderIsPluggedIn(configurationValues); return new StandardServiceRegistryScopedState( createMongoConfiguration(configurationValues, serviceRegistry)); } }); } - private MongoConfiguration createMongoConfiguration( + private static void checkMongoDialectIsPluggedIn( + Map configurationValues, ServiceRegistryImplementor serviceRegistry) { + var dialectFactory = serviceRegistry.getService(DialectFactory.class); + if ((dialectFactory == null + || dialectFactory.getClass().getPackageName().startsWith("org.hibernate")) + && configurationValues.get(AvailableSettings.DIALECT_RESOLVERS) == null) { + // If `DialectFactory` is different from the ones Hibernate ORM provide, or if + // `AvailableSettings.DIALECT_RESOLVERS` is specified, then we cannot detect whether + // `MongoDialect` is plugged in. Otherwise, we know that `AvailableSettings.DIALECT` + // is the only way to plug `MongoDialect` in, and we can detect whether it is plugged in. + var dialect = configurationValues.get(AvailableSettings.DIALECT); + if (!((dialect instanceof MongoDialect) + || (dialect instanceof Class dialectClass + && MongoDialect.class.isAssignableFrom(dialectClass)) + || (dialect instanceof String dialectName + && dialectName.startsWith("com.mongodb.hibernate")))) { + throw new RuntimeException("%s must be plugged in, for example, via the [%s] configuration property" + .formatted(MongoDialect.class.getName(), AvailableSettings.DIALECT)); + } + } + } + + private static void checkMongoConnectionProviderIsPluggedIn(Map configurationValues) { + var connectionProvider = configurationValues.get(AvailableSettings.CONNECTION_PROVIDER); + if (!((connectionProvider instanceof MongoConnectionProvider) + || (connectionProvider instanceof Class connectionProviderClass + && MongoConnectionProvider.class.isAssignableFrom(connectionProviderClass)) + || (connectionProvider instanceof String connectionProviderName + && connectionProviderName.startsWith("com.mongodb.hibernate")))) { + throw new RuntimeException("%s must be plugged in, for example, via the [%s] configuration property" + .formatted(MongoConnectionProvider.class.getName(), AvailableSettings.CONNECTION_PROVIDER)); + } + } + + private static MongoConfiguration createMongoConfiguration( Map configurationValues, ServiceRegistryImplementor serviceRegistry) { var jdbcUrl = configurationValues.get(JAKARTA_JDBC_URL); var mongoConfigurationContributor = getMongoConfigurationContributor(serviceRegistry); @@ -98,7 +138,7 @@ private MongoConfiguration createMongoConfiguration( return mongoConfigurationBuilder.build(); } - private @Nullable MongoConfigurationContributor getMongoConfigurationContributor( + private static @Nullable MongoConfigurationContributor getMongoConfigurationContributor( ServiceRegistryImplementor serviceRegistry) { MongoConfigurationContributor result = null; try { diff --git a/src/test/java/com/mongodb/hibernate/boot/NativeBootstrappingTests.java b/src/test/java/com/mongodb/hibernate/boot/NativeBootstrappingTests.java new file mode 100644 index 00000000..1d8d53d8 --- /dev/null +++ b/src/test/java/com/mongodb/hibernate/boot/NativeBootstrappingTests.java @@ -0,0 +1,89 @@ +/* + * Copyright 2024-present MongoDB, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.mongodb.hibernate.boot; + +import static org.assertj.core.api.Assertions.assertThatThrownBy; +import static org.hibernate.cfg.AvailableSettings.ALLOW_METADATA_ON_BOOT; +import static org.hibernate.cfg.AvailableSettings.DIALECT; +import static org.hibernate.cfg.AvailableSettings.JAKARTA_JDBC_URL; + +import com.mongodb.hibernate.internal.boot.MongoAdditionalMappingContributor; +import jakarta.persistence.Embeddable; +import jakarta.persistence.Entity; +import jakarta.persistence.Id; +import jakarta.persistence.Table; +import org.hibernate.InstantiationException; +import org.hibernate.boot.MetadataSources; +import org.hibernate.boot.registry.StandardServiceRegistryBuilder; +import org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl; +import org.junit.jupiter.api.Test; + +class NativeBootstrappingTests { + @Test + void testMongoDialectNotPluggedIn() { + try (var standardServiceRegistry = new StandardServiceRegistryBuilder() + .applySetting(DIALECT, "org.hibernate.dialect.PostgreSQLDialect") + .build()) { + assertThatThrownBy(() -> new MetadataSources() + .buildMetadata(standardServiceRegistry) + .buildSessionFactory() + .close()) + .hasRootCauseMessage("com.mongodb.hibernate.dialect.MongoDialect must be plugged in" + + ", for example, via the [hibernate.dialect] configuration property"); + } + } + + /** + * Verify that {@link MongoAdditionalMappingContributor} skips its logic when bootstrapping is unrelated to the + * MongoDB Extension for Hibernate ORM. + */ + @Test + void testMongoAdditionalMappingContributorIsSkipped() { + var standardServiceRegistryBuilder = new StandardServiceRegistryBuilder(); + standardServiceRegistryBuilder.clearSettings(); + try (var sessionFactory = new MetadataSources() + .addAnnotatedClass(Item.class) + .buildMetadata(standardServiceRegistryBuilder + .applySetting(DIALECT, "org.hibernate.dialect.PostgreSQLDialect") + .applySetting(JAKARTA_JDBC_URL, "jdbc:postgresql://host/") + .applySetting(ALLOW_METADATA_ON_BOOT, false) + .applySetting(DriverManagerConnectionProviderImpl.INITIAL_SIZE, 0) + .build()) + .buildSessionFactory()) { + assertThatThrownBy(() -> sessionFactory.inSession(session -> session.persist(new Item(null)))) + .hasMessageNotContaining("does not support primary key spanning multiple columns") + .isInstanceOf(InstantiationException.class) + .hasMessageMatching("Could not instantiate entity .* due to: null"); + } + } + + @Entity + @Table(name = Item.COLLECTION_NAME) + static class Item { + static final String COLLECTION_NAME = "items"; + + @Id + MultipleColumns id; + + Item(MultipleColumns id) { + this.id = id; + } + + @Embeddable + record MultipleColumns(int a, int b) {} + } +} diff --git a/src/test/java/com/mongodb/hibernate/internal/service/StandardServiceRegistryScopedStateTests.java b/src/test/java/com/mongodb/hibernate/internal/service/StandardServiceRegistryScopedStateTests.java index 22e38af2..28d99663 100644 --- a/src/test/java/com/mongodb/hibernate/internal/service/StandardServiceRegistryScopedStateTests.java +++ b/src/test/java/com/mongodb/hibernate/internal/service/StandardServiceRegistryScopedStateTests.java @@ -16,6 +16,8 @@ package com.mongodb.hibernate.internal.service; +import static org.assertj.core.api.Assertions.assertThatThrownBy; +import static org.hibernate.cfg.AvailableSettings.DIALECT; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNotSame; @@ -65,4 +67,28 @@ void mongoConfigurationContributorInvocationsAndMongoConfiguratorInstances() { } } } + + @Test + void testMongoDialectNotPluggedIn() { + var standardServiceRegistryBuilder = new StandardServiceRegistryBuilder(); + standardServiceRegistryBuilder.clearSettings(); + try (var standardServiceRegistry = standardServiceRegistryBuilder.build()) { + assertThatThrownBy(() -> standardServiceRegistry.requireService(StandardServiceRegistryScopedState.class)) + .hasRootCauseMessage("com.mongodb.hibernate.dialect.MongoDialect must be plugged in" + + ", for example, via the [hibernate.dialect] configuration property"); + } + } + + @Test + void testMongoConnectionProviderNotPluggedIn() { + var standardServiceRegistryBuilder = new StandardServiceRegistryBuilder(); + standardServiceRegistryBuilder.clearSettings(); + try (var standardServiceRegistry = standardServiceRegistryBuilder + .applySetting(DIALECT, "com.mongodb.hibernate.dialect.MongoDialect") + .build()) { + assertThatThrownBy(() -> standardServiceRegistry.requireService(StandardServiceRegistryScopedState.class)) + .hasRootCauseMessage("com.mongodb.hibernate.jdbc.MongoConnectionProvider must be plugged in" + + ", for example, via the [hibernate.connection.provider_class] configuration property"); + } + } } diff --git a/src/test/java/com/mongodb/hibernate/service/MongoConfigurationContributorTests.java b/src/test/java/com/mongodb/hibernate/service/MongoConfigurationContributorTests.java index 2e7f7b5d..05ab8ec3 100644 --- a/src/test/java/com/mongodb/hibernate/service/MongoConfigurationContributorTests.java +++ b/src/test/java/com/mongodb/hibernate/service/MongoConfigurationContributorTests.java @@ -60,13 +60,11 @@ void exceptionPropagates() { } private static SessionFactory buildSessionFactory(MongoConfigurationContributor mongoConfigurationContributor) { - return new MetadataSources(new StandardServiceRegistryBuilder() + return new MetadataSources() + .buildMetadata(new StandardServiceRegistryBuilder() .addService(MongoConfigurationContributor.class, mongoConfigurationContributor) .build()) - .getMetadataBuilder() - .build() - .getSessionFactoryBuilder() - .build(); + .buildSessionFactory(); } private static class TestClusterListener implements ClusterListener { From 6e189547034a591463ac451cb1ce2fd2803940c7 Mon Sep 17 00:00:00 2001 From: Valentin Kovalenko Date: Fri, 21 Nov 2025 16:56:20 -0700 Subject: [PATCH 4/4] Use static imports HIBERNATE-135 --- .../service/StandardServiceRegistryScopedState.java | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/main/java/com/mongodb/hibernate/internal/service/StandardServiceRegistryScopedState.java b/src/main/java/com/mongodb/hibernate/internal/service/StandardServiceRegistryScopedState.java index 5a274439..c2a34fc3 100644 --- a/src/main/java/com/mongodb/hibernate/internal/service/StandardServiceRegistryScopedState.java +++ b/src/main/java/com/mongodb/hibernate/internal/service/StandardServiceRegistryScopedState.java @@ -18,6 +18,7 @@ import static com.mongodb.hibernate.internal.VisibleForTesting.AccessModifier.PRIVATE; import static java.lang.String.format; +import static org.hibernate.cfg.AvailableSettings.DIALECT_RESOLVERS; import static org.hibernate.cfg.AvailableSettings.JAKARTA_JDBC_URL; import static org.hibernate.cfg.AvailableSettings.JAVA_TIME_USE_DIRECT_JDBC; import static org.hibernate.cfg.AvailableSettings.PREFERRED_INSTANT_JDBC_TYPE; @@ -92,11 +93,11 @@ private static void checkMongoDialectIsPluggedIn( var dialectFactory = serviceRegistry.getService(DialectFactory.class); if ((dialectFactory == null || dialectFactory.getClass().getPackageName().startsWith("org.hibernate")) - && configurationValues.get(AvailableSettings.DIALECT_RESOLVERS) == null) { - // If `DialectFactory` is different from the ones Hibernate ORM provide, or if - // `AvailableSettings.DIALECT_RESOLVERS` is specified, then we cannot detect whether - // `MongoDialect` is plugged in. Otherwise, we know that `AvailableSettings.DIALECT` - // is the only way to plug `MongoDialect` in, and we can detect whether it is plugged in. + && configurationValues.get(DIALECT_RESOLVERS) == null) { + // If `DialectFactory` is different from the ones Hibernate ORM provides, or if + // `DIALECT_RESOLVERS` is specified, then we cannot detect whether `MongoDialect` is plugged in. + // Otherwise, we know that `DIALECT` is the only way to plug `MongoDialect` in, + // and we can detect whether it is plugged in. var dialect = configurationValues.get(AvailableSettings.DIALECT); if (!((dialect instanceof MongoDialect) || (dialect instanceof Class dialectClass