From d7bd82c643f27562cf19544905467bf2113f921a Mon Sep 17 00:00:00 2001 From: Thomas Darimont Date: Mon, 27 Oct 2014 16:31:54 +0100 Subject: [PATCH] DATAMONGO-1076 - Avoid resolving lazy-loading proxy for DBRefs during finalize. We now handle intercepted finalize method invocations by not resolving the proxy. Previously the LazyLoadingProxy tried to resolve the proxy during finalization which could lead to unnecessary database accesses. Original pull request: #234. --- .../core/convert/DefaultDbRefResolver.java | 8 +++++++- .../DbRefMappingMongoConverterUnitTests.java | 20 +++++++++++++++++++ 2 files changed, 27 insertions(+), 1 deletion(-) 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 37c6fbbac..8b64c7cb9 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 @@ -178,7 +178,7 @@ public class DefaultDbRefResolver implements DbRefResolver { static class LazyLoadingInterceptor implements MethodInterceptor, org.springframework.cglib.proxy.MethodInterceptor, Serializable { - private static final Method INITIALIZE_METHOD, TO_DBREF_METHOD; + private static final Method INITIALIZE_METHOD, TO_DBREF_METHOD, FINALIZE_METHOD; private final DbRefResolverCallback callback; private final MongoPersistentProperty property; @@ -192,6 +192,7 @@ public class DefaultDbRefResolver implements DbRefResolver { try { INITIALIZE_METHOD = LazyLoadingProxy.class.getMethod("getTarget"); TO_DBREF_METHOD = LazyLoadingProxy.class.getMethod("toDBRef"); + FINALIZE_METHOD = Object.class.getDeclaredMethod("finalize"); } catch (Exception e) { throw new RuntimeException(e); } @@ -255,6 +256,11 @@ public class DefaultDbRefResolver implements DbRefResolver { if (ReflectionUtils.isHashCodeMethod(method)) { return proxyHashCode(proxy); } + + // DATAMONGO-1076 - finalize methods should not trigger proxy initialization + if (FINALIZE_METHOD.equals(method)) { + return null; + } } Object target = ensureResolved(); diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/convert/DbRefMappingMongoConverterUnitTests.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/convert/DbRefMappingMongoConverterUnitTests.java index 73252ee50..fec18436a 100644 --- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/convert/DbRefMappingMongoConverterUnitTests.java +++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/convert/DbRefMappingMongoConverterUnitTests.java @@ -541,6 +541,26 @@ public class DbRefMappingMongoConverterUnitTests { assertProxyIsResolved(proxy, false); } + /** + * @see DATAMONGO-1076 + */ + @Test + public void shouldNotTriggerResolvingOfLazyLoadedProxyWhenFinalizeMethodIsInvoked() throws Exception { + + MongoPersistentEntity entity = mappingContext.getPersistentEntity(WithObjectMethodOverrideLazyDbRefs.class); + MongoPersistentProperty property = entity.getPersistentProperty("dbRefToConcreteTypeWithPropertyAccess"); + + String idValue = new ObjectId().toString(); + DBRef dbRef = converter.toDBRef(new LazyDbRefTargetPropertyAccess(idValue), property); + + WithObjectMethodOverrideLazyDbRefs result = converter.read(WithObjectMethodOverrideLazyDbRefs.class, + new BasicDBObject("dbRefToPlainObject", dbRef)); + + ReflectionTestUtils.invokeMethod(result.dbRefToPlainObject, "finalize"); + + assertProxyIsResolved(result.dbRefToPlainObject, false); + } + private Object transport(Object result) { return SerializationUtils.deserialize(SerializationUtils.serialize(result)); }