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.
This commit is contained in:
Thomas Darimont
2014-10-27 16:31:54 +01:00
committed by Oliver Gierke
parent 078cca83e3
commit d7bd82c643
2 changed files with 27 additions and 1 deletions

View File

@@ -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();

View File

@@ -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));
}