-
Notifications
You must be signed in to change notification settings - Fork 13
Make sure our extension does not interfere when bootstrapping is unrelated to it #146
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from 1 commit
9db8582
9d11a0b
f7dbe58
6e18954
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
|
This file was deleted.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -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<BsonDocument> mongoCollection; | ||
|
|
||
| @Test | ||
| void smoke(EntityManagerFactoryScope scope) { | ||
| scope.inTransaction(em -> { | ||
| var item = new Item(); | ||
| item.id = 1; | ||
| em.persist(item); | ||
| }); | ||
|
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Only drive-by changes here to make the test code simpler. |
||
| 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; | ||
| } | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -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") | ||
vbabanin marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| 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"); | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -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) {} | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -14,7 +14,7 @@ | |
| * limitations under the License. | ||
| */ | ||
|
|
||
| package com.mongodb.hibernate.internal.extension; | ||
| package com.mongodb.hibernate.internal.boot; | ||
|
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
|
|
||
| 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; | ||
| } | ||
|
Comment on lines
+81
to
+90
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is the actual fix. |
||
| forbidEmbeddablesWithoutPersistentAttributes(metadata); | ||
| metadata.getEntityBindings().forEach(persistentClass -> { | ||
| checkPropertyTypes(persistentClass); | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -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() {} | ||
|
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Made the constructor used by Hibernate ORM explicit, like we do in other places. |
||
|
|
||
| @Override | ||
| public Connection getConnection() throws SQLException { | ||
| try { | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1 +1,5 @@ | ||
| com.mongodb.hibernate.internal.extension.MongoAdditionalMappingContributor | ||
| # 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 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Test classes should have the "Tests" suffix.