DATAMONGO-348 - Added serialization support for lazy-loading for DBRefs.
This commit is contained in:
committed by
Oliver Gierke
parent
df1c4496dc
commit
8fb390ee88
@@ -15,6 +15,10 @@
|
||||
*/
|
||||
package org.springframework.data.mongodb.core.convert;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.ObjectInputStream;
|
||||
import java.io.ObjectOutputStream;
|
||||
import java.io.Serializable;
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
import org.aopalliance.intercept.MethodInterceptor;
|
||||
@@ -150,7 +154,8 @@ public class DefaultDbRefResolver implements DbRefResolver {
|
||||
*
|
||||
* @author Thomas Darimont
|
||||
*/
|
||||
static class LazyLoadingInterceptor implements MethodInterceptor, org.springframework.cglib.proxy.MethodInterceptor {
|
||||
static class LazyLoadingInterceptor implements MethodInterceptor, org.springframework.cglib.proxy.MethodInterceptor,
|
||||
Serializable {
|
||||
|
||||
private final DbRefResolverCallback callback;
|
||||
private final MongoPersistentProperty property;
|
||||
@@ -194,12 +199,33 @@ public class DefaultDbRefResolver implements DbRefResolver {
|
||||
@Override
|
||||
public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
|
||||
|
||||
ensureResolved();
|
||||
|
||||
return method.invoke(result, args);
|
||||
}
|
||||
|
||||
private void ensureResolved() {
|
||||
|
||||
if (!resolved) {
|
||||
this.result = resolve();
|
||||
this.resolved = true;
|
||||
}
|
||||
}
|
||||
|
||||
return method.invoke(result, args);
|
||||
private void writeObject(ObjectOutputStream out) throws IOException {
|
||||
|
||||
ensureResolved();
|
||||
out.writeObject(this.result);
|
||||
}
|
||||
|
||||
private void readObject(ObjectInputStream in) throws IOException {
|
||||
|
||||
try {
|
||||
this.resolved = true; // Object is guaranteed to be resolved after serializations
|
||||
this.result = in.readObject();
|
||||
} catch (ClassNotFoundException e) {
|
||||
throw new LazyLoadingException("Could not deserialize result", e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -21,6 +21,7 @@ import static org.mockito.Matchers.*;
|
||||
import static org.mockito.Mockito.*;
|
||||
import static org.springframework.data.mongodb.core.convert.LazyLoadingTestUtils.*;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.math.BigInteger;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
@@ -42,6 +43,7 @@ import org.springframework.data.mongodb.core.MongoExceptionTranslator;
|
||||
import org.springframework.data.mongodb.core.convert.MappingMongoConverterUnitTests.Person;
|
||||
import org.springframework.data.mongodb.core.mapping.MongoMappingContext;
|
||||
import org.springframework.data.mongodb.core.mapping.MongoPersistentProperty;
|
||||
import org.springframework.util.SerializationUtils;
|
||||
|
||||
import com.mongodb.BasicDBObject;
|
||||
import com.mongodb.DBObject;
|
||||
@@ -256,6 +258,35 @@ public class DbRefMappingMongoConverterUnitTests {
|
||||
assertThat(result.dbRefToConcreteTypeWithPersistenceConstructorWithoutDefaultConstructor.getValue(), is(value));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATAMONGO-348
|
||||
*/
|
||||
@Test
|
||||
public void lazyLoadingProxyForSerializableLazyDbRefOnConcreteType() {
|
||||
|
||||
String id = "42";
|
||||
String value = "bubu";
|
||||
MappingMongoConverter converterSpy = spy(converter);
|
||||
doReturn(new BasicDBObject("_id", id).append("value", value)).when(converterSpy).readRef((DBRef) any());
|
||||
|
||||
BasicDBObject dbo = new BasicDBObject();
|
||||
SerializableClassWithLazyDbRefs lazyDbRefs = new SerializableClassWithLazyDbRefs();
|
||||
lazyDbRefs.dbRefToSerializableTarget = new SerializableLazyDbRefTarget(id, value);
|
||||
converterSpy.write(lazyDbRefs, dbo);
|
||||
|
||||
SerializableClassWithLazyDbRefs result = converterSpy.read(SerializableClassWithLazyDbRefs.class, dbo);
|
||||
|
||||
SerializableClassWithLazyDbRefs deserializedResult = (SerializableClassWithLazyDbRefs) transport(result);
|
||||
|
||||
assertThat(deserializedResult.dbRefToSerializableTarget.getId(), is(id));
|
||||
assertProxyIsResolved(deserializedResult.dbRefToSerializableTarget, true);
|
||||
assertThat(deserializedResult.dbRefToSerializableTarget.getValue(), is(value));
|
||||
}
|
||||
|
||||
private Object transport(Object result) {
|
||||
return SerializationUtils.deserialize(SerializationUtils.serialize(result));
|
||||
}
|
||||
|
||||
class MapDBRef {
|
||||
@org.springframework.data.mongodb.core.mapping.DBRef Map<String, MapDBRefVal> map;
|
||||
}
|
||||
@@ -278,7 +309,16 @@ public class DbRefMappingMongoConverterUnitTests {
|
||||
@org.springframework.data.mongodb.core.mapping.DBRef(lazy = true) LazyDbRefTargetWithPeristenceConstructorWithoutDefaultConstructor dbRefToConcreteTypeWithPersistenceConstructorWithoutDefaultConstructor;
|
||||
}
|
||||
|
||||
static class LazyDbRefTarget {
|
||||
static class SerializableClassWithLazyDbRefs implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@org.springframework.data.mongodb.core.mapping.DBRef(lazy = true) SerializableLazyDbRefTarget dbRefToSerializableTarget;
|
||||
}
|
||||
|
||||
static class LazyDbRefTarget implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@Id String id;
|
||||
String value;
|
||||
@@ -336,4 +376,15 @@ public class DbRefMappingMongoConverterUnitTests {
|
||||
super(id.toString(), value.toString());
|
||||
}
|
||||
}
|
||||
|
||||
static class SerializableLazyDbRefTarget extends LazyDbRefTarget implements Serializable {
|
||||
|
||||
public SerializableLazyDbRefTarget() {}
|
||||
|
||||
public SerializableLazyDbRefTarget(String id, String value) {
|
||||
super(id, value);
|
||||
}
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user