Browse Source

DATAMONGO-1012 - Improved identifier initialization on DBRef proxies.

Identifier initalization is now only triggered if field access is used. Before that the id initialization would've resolved the proxy eagerly as the getter access performed by the BeanWrapper would've been intercepted by the proxy and is indistinguishable from a normal method call. This would've rendered the entire use case to create proxies ad absurdum.

Added test case to check for non-initialization in the property access scenario.
pull/216/merge
Thomas Darimont 12 years ago committed by Oliver Gierke
parent
commit
3597194742
  1. 2
      spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/DefaultDbRefProxyHandler.java
  2. 49
      spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/convert/DbRefMappingMongoConverterUnitTests.java

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

@ -63,7 +63,7 @@ class DefaultDbRefProxyHandler implements DbRefProxyHandler {
MongoPersistentEntity<?> persistentEntity = mappingContext.getPersistentEntity(property); MongoPersistentEntity<?> persistentEntity = mappingContext.getPersistentEntity(property);
MongoPersistentProperty idProperty = persistentEntity.getIdProperty(); MongoPersistentProperty idProperty = persistentEntity.getIdProperty();
if (idProperty.usePropertyAccess()) { if(idProperty.usePropertyAccess()) {
return proxy; return proxy;
} }

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

@ -36,6 +36,8 @@ import org.junit.Test;
import org.junit.runner.RunWith; import org.junit.runner.RunWith;
import org.mockito.Mock; import org.mockito.Mock;
import org.mockito.runners.MockitoJUnitRunner; import org.mockito.runners.MockitoJUnitRunner;
import org.springframework.data.annotation.AccessType;
import org.springframework.data.annotation.AccessType.Type;
import org.springframework.data.annotation.Id; import org.springframework.data.annotation.Id;
import org.springframework.data.annotation.PersistenceConstructor; import org.springframework.data.annotation.PersistenceConstructor;
import org.springframework.data.mapping.PropertyPath; import org.springframework.data.mapping.PropertyPath;
@ -46,6 +48,7 @@ import org.springframework.data.mongodb.core.convert.MappingMongoConverterUnitTe
import org.springframework.data.mongodb.core.mapping.MongoMappingContext; import org.springframework.data.mongodb.core.mapping.MongoMappingContext;
import org.springframework.data.mongodb.core.mapping.MongoPersistentEntity; import org.springframework.data.mongodb.core.mapping.MongoPersistentEntity;
import org.springframework.data.mongodb.core.mapping.MongoPersistentProperty; import org.springframework.data.mongodb.core.mapping.MongoPersistentProperty;
import org.springframework.test.util.ReflectionTestUtils;
import org.springframework.util.SerializationUtils; import org.springframework.util.SerializationUtils;
import com.mongodb.BasicDBObject; import com.mongodb.BasicDBObject;
@ -494,13 +497,17 @@ public class DbRefMappingMongoConverterUnitTests {
assertThat(found.nested.reference, is(found)); assertThat(found.nested.reference, is(found));
} }
/**
* @see DATAMONGO-1012
*/
@Test @Test
public void testname() { public void shouldEagerlyResolveIdPropertyWithFieldAccess() {
MongoPersistentEntity<?> entity = mappingContext.getPersistentEntity(ClassWithLazyDbRefs.class); MongoPersistentEntity<?> entity = mappingContext.getPersistentEntity(ClassWithLazyDbRefs.class);
MongoPersistentProperty property = entity.getPersistentProperty("dbRefToConcreteType"); MongoPersistentProperty property = entity.getPersistentProperty("dbRefToConcreteType");
Object dbRef = converter.toDBRef(new LazyDbRefTarget(new ObjectId().toString()), property); String idValue = new ObjectId().toString();
DBRef dbRef = converter.toDBRef(new LazyDbRefTarget(idValue), property);
DBObject object = new BasicDBObject("dbRefToConcreteType", dbRef); DBObject object = new BasicDBObject("dbRefToConcreteType", dbRef);
@ -510,6 +517,28 @@ public class DbRefMappingMongoConverterUnitTests {
MongoPersistentProperty idProperty = mappingContext.getPersistentEntity(LazyDbRefTarget.class).getIdProperty(); MongoPersistentProperty idProperty = mappingContext.getPersistentEntity(LazyDbRefTarget.class).getIdProperty();
assertThat(wrapper.getProperty(idProperty), is(notNullValue())); assertThat(wrapper.getProperty(idProperty), is(notNullValue()));
assertProxyIsResolved(result.dbRefToConcreteType, false);
}
/**
* @see DATAMONGO-1012
*/
@Test
public void shouldNotEagerlyResolveIdPropertyWithPropertyAccess() {
MongoPersistentEntity<?> entity = mappingContext.getPersistentEntity(ClassWithLazyDbRefs.class);
MongoPersistentProperty property = entity.getPersistentProperty("dbRefToConcreteTypeWithPropertyAccess");
String idValue = new ObjectId().toString();
DBRef dbRef = converter.toDBRef(new LazyDbRefTargetPropertyAccess(idValue), property);
DBObject object = new BasicDBObject("dbRefToConcreteTypeWithPropertyAccess", dbRef);
ClassWithLazyDbRefs result = converter.read(ClassWithLazyDbRefs.class, object);
LazyDbRefTargetPropertyAccess proxy = result.dbRefToConcreteTypeWithPropertyAccess;
assertThat(ReflectionTestUtils.getField(proxy, "id"), is(nullValue()));
assertProxyIsResolved(proxy, false);
} }
private Object transport(Object result) { private Object transport(Object result) {
@ -534,6 +563,7 @@ public class DbRefMappingMongoConverterUnitTests {
@org.springframework.data.mongodb.core.mapping.DBRef(lazy = true) List<LazyDbRefTarget> dbRefToInterface; @org.springframework.data.mongodb.core.mapping.DBRef(lazy = true) List<LazyDbRefTarget> dbRefToInterface;
@org.springframework.data.mongodb.core.mapping.DBRef(lazy = true) ArrayList<LazyDbRefTarget> dbRefToConcreteCollection; @org.springframework.data.mongodb.core.mapping.DBRef(lazy = true) ArrayList<LazyDbRefTarget> dbRefToConcreteCollection;
@org.springframework.data.mongodb.core.mapping.DBRef(lazy = true) LazyDbRefTarget dbRefToConcreteType; @org.springframework.data.mongodb.core.mapping.DBRef(lazy = true) LazyDbRefTarget dbRefToConcreteType;
@org.springframework.data.mongodb.core.mapping.DBRef(lazy = true) LazyDbRefTargetPropertyAccess dbRefToConcreteTypeWithPropertyAccess;
@org.springframework.data.mongodb.core.mapping.DBRef(lazy = true) LazyDbRefTargetWithPeristenceConstructor dbRefToConcreteTypeWithPersistenceConstructor; @org.springframework.data.mongodb.core.mapping.DBRef(lazy = true) LazyDbRefTargetWithPeristenceConstructor dbRefToConcreteTypeWithPersistenceConstructor;
@org.springframework.data.mongodb.core.mapping.DBRef(lazy = true) LazyDbRefTargetWithPeristenceConstructorWithoutDefaultConstructor dbRefToConcreteTypeWithPersistenceConstructorWithoutDefaultConstructor; @org.springframework.data.mongodb.core.mapping.DBRef(lazy = true) LazyDbRefTargetWithPeristenceConstructorWithoutDefaultConstructor dbRefToConcreteTypeWithPersistenceConstructorWithoutDefaultConstructor;
} }
@ -574,6 +604,21 @@ public class DbRefMappingMongoConverterUnitTests {
} }
} }
static class LazyDbRefTargetPropertyAccess implements Serializable {
private static final long serialVersionUID = 1L;
@Id @AccessType(Type.PROPERTY) String id;
public LazyDbRefTargetPropertyAccess(String id) {
this.id = id;
}
public String getId() {
return id;
}
}
@SuppressWarnings("serial") @SuppressWarnings("serial")
static class LazyDbRefTargetWithPeristenceConstructor extends LazyDbRefTarget { static class LazyDbRefTargetWithPeristenceConstructor extends LazyDbRefTarget {

Loading…
Cancel
Save