Skip to content

Commit c076e13

Browse files
author
Thomas Darimont
committed
DATAMONGO-1076 - Avoid resolving lazy-loading proxy for dbrefs during finalize.
We now handle intercepted finalize method invocations by not trying to resolve the proxy. Previously the LazyLoadingProxy tried to resolve the proxy during finalisation which could lead to unnecessary database accesses.
1 parent 3b930a0 commit c076e13

File tree

2 files changed

+31
-1
lines changed

2 files changed

+31
-1
lines changed

spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/DefaultDbRefResolver.java

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -178,7 +178,7 @@ private boolean isLazyDbRef(MongoPersistentProperty property) {
178178
static class LazyLoadingInterceptor implements MethodInterceptor, org.springframework.cglib.proxy.MethodInterceptor,
179179
Serializable {
180180

181-
private static final Method INITIALIZE_METHOD, TO_DBREF_METHOD;
181+
private static final Method INITIALIZE_METHOD, TO_DBREF_METHOD, FINALIZE_METHOD;
182182

183183
private final DbRefResolverCallback callback;
184184
private final MongoPersistentProperty property;
@@ -192,6 +192,7 @@ static class LazyLoadingInterceptor implements MethodInterceptor, org.springfram
192192
try {
193193
INITIALIZE_METHOD = LazyLoadingProxy.class.getMethod("getTarget");
194194
TO_DBREF_METHOD = LazyLoadingProxy.class.getMethod("toDBRef");
195+
FINALIZE_METHOD = Object.class.getDeclaredMethod("finalize");
195196
} catch (Exception e) {
196197
throw new RuntimeException(e);
197198
}
@@ -255,6 +256,11 @@ public Object intercept(Object obj, Method method, Object[] args, MethodProxy pr
255256
if (ReflectionUtils.isHashCodeMethod(method)) {
256257
return proxyHashCode(proxy);
257258
}
259+
260+
// DATAMONGO-1076 - finalize methods should not trigger proxy initialization
261+
if (FINALIZE_METHOD.equals(method)) {
262+
return null;
263+
}
258264
}
259265

260266
Object target = ensureResolved();

spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/convert/DbRefMappingMongoConverterUnitTests.java

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
import static org.springframework.data.mongodb.core.convert.LazyLoadingTestUtils.*;
2323

2424
import java.io.Serializable;
25+
import java.lang.reflect.Method;
2526
import java.math.BigInteger;
2627
import java.util.ArrayList;
2728
import java.util.Arrays;
@@ -49,6 +50,7 @@
4950
import org.springframework.data.mongodb.core.mapping.MongoPersistentEntity;
5051
import org.springframework.data.mongodb.core.mapping.MongoPersistentProperty;
5152
import org.springframework.test.util.ReflectionTestUtils;
53+
import org.springframework.util.ReflectionUtils;
5254
import org.springframework.util.SerializationUtils;
5355

5456
import com.mongodb.BasicDBObject;
@@ -541,6 +543,28 @@ public void shouldNotEagerlyResolveIdPropertyWithPropertyAccess() {
541543
assertProxyIsResolved(proxy, false);
542544
}
543545

546+
/**
547+
* @see DATAMONGO-1076
548+
*/
549+
@Test
550+
public void shouldNotTriggerResolvingOfLazyLoadedProxyWhenFinalizeMethodIsInvoked() throws Exception {
551+
552+
MongoPersistentEntity<?> entity = mappingContext.getPersistentEntity(WithObjectMethodOverrideLazyDbRefs.class);
553+
MongoPersistentProperty property = entity.getPersistentProperty("dbRefToConcreteTypeWithPropertyAccess");
554+
555+
String idValue = new ObjectId().toString();
556+
DBRef dbRef = converter.toDBRef(new LazyDbRefTargetPropertyAccess(idValue), property);
557+
558+
WithObjectMethodOverrideLazyDbRefs result = converter.read(WithObjectMethodOverrideLazyDbRefs.class,
559+
new BasicDBObject("dbRefToPlainObject", dbRef));
560+
561+
Method finalize = Object.class.getDeclaredMethod("finalize");
562+
ReflectionUtils.makeAccessible(finalize);
563+
ReflectionUtils.invokeMethod(finalize, result.dbRefToPlainObject);
564+
565+
assertProxyIsResolved(result.dbRefToPlainObject, false);
566+
}
567+
544568
private Object transport(Object result) {
545569
return SerializationUtils.deserialize(SerializationUtils.serialize(result));
546570
}

0 commit comments

Comments
 (0)