From d65be17338422531a6cdb58b1b77b76be1bdb9d0 Mon Sep 17 00:00:00 2001 From: Christoph Strobl Date: Thu, 2 Apr 2015 10:13:49 +0200 Subject: [PATCH] DATAMONGO-1193 - Prevent unnecessary database lookups when resolving DBRefs on 2.x driver. We now check against the used driver version before requesting db instance from factory. Potential improvements on fetch strategy for MongoDB Java Driver 3 will be handled in DATAMONGO-1194. Related tickets: DATAMONGO-1194. Original pull request: #286. --- .../core/convert/DefaultDbRefResolver.java | 2 +- .../core/convert/ReflectiveDBRefResolver.java | 8 +- .../ReflectiveDBRefResolverUnitTests.java | 97 +++++++++++++++++++ 3 files changed, 103 insertions(+), 4 deletions(-) create mode 100644 spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/convert/ReflectiveDBRefResolverUnitTests.java diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/DefaultDbRefResolver.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/DefaultDbRefResolver.java index ddea7ff5c..7e543e857 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/DefaultDbRefResolver.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/DefaultDbRefResolver.java @@ -106,7 +106,7 @@ public class DefaultDbRefResolver implements DbRefResolver { */ @Override public DBObject fetch(DBRef dbRef) { - return ReflectiveDBRefResolver.fetch(mongoDbFactory.getDb(), dbRef); + return ReflectiveDBRefResolver.fetch(mongoDbFactory, dbRef); } /** diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/ReflectiveDBRefResolver.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/ReflectiveDBRefResolver.java index ae59361d5..8537e2933 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/ReflectiveDBRefResolver.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/ReflectiveDBRefResolver.java @@ -20,9 +20,9 @@ import static org.springframework.util.ReflectionUtils.*; import java.lang.reflect.Method; +import org.springframework.data.mongodb.MongoDbFactory; import org.springframework.util.Assert; -import com.mongodb.DB; import com.mongodb.DBCollection; import com.mongodb.DBObject; import com.mongodb.DBRef; @@ -51,12 +51,14 @@ class ReflectiveDBRefResolver { * @param ref must not be {@literal null}. * @return the document that this references. */ - public static DBObject fetch(DB db, DBRef ref) { + public static DBObject fetch(MongoDbFactory factory, DBRef ref) { Assert.notNull(ref, "DBRef to fetch must not be null!"); if (isMongo3Driver()) { - return db.getCollection(ref.getCollectionName()).findOne(ref.getId()); + + Assert.notNull(factory, "DbFactory to fetch DB from must not be null!"); + return factory.getDb().getCollection(ref.getCollectionName()).findOne(ref.getId()); } return (DBObject) invokeMethod(FETCH_METHOD, ref); diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/convert/ReflectiveDBRefResolverUnitTests.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/convert/ReflectiveDBRefResolverUnitTests.java new file mode 100644 index 000000000..01b105540 --- /dev/null +++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/convert/ReflectiveDBRefResolverUnitTests.java @@ -0,0 +1,97 @@ +/* + * Copyright 2015 the original author or authors. + * + * 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 org.springframework.data.mongodb.core.convert; + +import static org.hamcrest.core.Is.*; +import static org.hamcrest.core.IsNull.*; +import static org.junit.Assert.*; +import static org.junit.Assume.*; +import static org.mockito.Matchers.*; +import static org.mockito.Mockito.*; +import static org.springframework.data.mongodb.util.MongoClientVersion.*; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.runners.MockitoJUnitRunner; +import org.springframework.data.mongodb.MongoDbFactory; + +import com.mongodb.BasicDBObject; +import com.mongodb.DB; +import com.mongodb.DBCollection; +import com.mongodb.DBRef; + +/** + * Unit tests for {@link ReflectiveDBRefResolver}. + * + * @author Christoph Strobl + */ +@RunWith(MockitoJUnitRunner.class) +public class ReflectiveDBRefResolverUnitTests { + + @Mock MongoDbFactory dbFactoryMock; + @Mock DBRef dbRefMock; + @Mock DB dbMock; + @Mock DBCollection collectionMock; + + @Before + public void setUp() { + + when(dbRefMock.getCollectionName()).thenReturn("collection-1"); + when(dbRefMock.getId()).thenReturn("id-1"); + when(dbFactoryMock.getDb()).thenReturn(dbMock); + when(dbMock.getCollection(eq("collection-1"))).thenReturn(collectionMock); + when(collectionMock.findOne(eq("id-1"))).thenReturn(new BasicDBObject("_id", "id-1")); + } + + /** + * @see DATAMONGO-1193 + */ + @Test + public void fetchShouldNotLookUpDbWhenUsingDriverVersion2() { + + assumeThat(isMongo3Driver(), is(false)); + + ReflectiveDBRefResolver.fetch(dbFactoryMock, dbRefMock); + + verify(dbFactoryMock, never()).getDb(); + verify(dbFactoryMock, never()).getDb(anyString()); + } + + /** + * @see DATAMONGO-1193 + */ + @Test + public void fetchShouldUseDbToResolveDbRefWhenUsingDriverVersion3() { + + assumeThat(isMongo3Driver(), is(true)); + + assertThat(ReflectiveDBRefResolver.fetch(dbFactoryMock, dbRefMock), notNullValue()); + verify(dbFactoryMock, times(1)).getDb(); + } + + /** + * @see DATAMONGO-1193 + */ + @Test(expected = IllegalArgumentException.class) + public void fetchShouldThrowExceptionWhenDbFactoryIsNullUsingDriverVersion3() { + + assumeThat(isMongo3Driver(), is(true)); + + ReflectiveDBRefResolver.fetch(null, dbRefMock); + } +}