Fixes for bug skipping fields in superclasses
This commit is contained in:
@@ -36,7 +36,6 @@
|
||||
<dependency>
|
||||
<groupId>org.springframework.data</groupId>
|
||||
<artifactId>spring-data-document-core</artifactId>
|
||||
<version>1.0.0.BUILD-SNAPSHOT</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.data</groupId>
|
||||
|
||||
@@ -24,6 +24,7 @@ import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.bson.types.ObjectId;
|
||||
import org.springframework.beans.BeansException;
|
||||
import org.springframework.beans.factory.InitializingBean;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.ApplicationContextAware;
|
||||
@@ -40,12 +41,9 @@ import org.springframework.expression.spel.standard.SpelExpressionParser;
|
||||
import org.springframework.expression.spel.support.StandardEvaluationContext;
|
||||
|
||||
import java.lang.reflect.Array;
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.math.BigInteger;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.ConcurrentMap;
|
||||
|
||||
/**
|
||||
* @author Jon Brisbin <jbrisbin@vmware.com>
|
||||
@@ -54,7 +52,6 @@ import java.util.concurrent.ConcurrentMap;
|
||||
public class MappingMongoConverter implements MongoConverter, ApplicationContextAware {
|
||||
|
||||
protected static final Log log = LogFactory.getLog(MappingMongoConverter.class);
|
||||
protected static final ConcurrentMap<Class<?>, Map<String, Field>> fieldsByName = new ConcurrentHashMap<Class<?>, Map<String, Field>>();
|
||||
|
||||
protected GenericConversionService conversionService = ConversionServiceFactory.createDefaultConversionService();
|
||||
protected SpelExpressionParser spelExpressionParser = new SpelExpressionParser();
|
||||
@@ -223,6 +220,13 @@ public class MappingMongoConverter implements MongoConverter, ApplicationContext
|
||||
if (null != applicationContext && autowirePersistentBeans) {
|
||||
applicationContext.getAutowireCapableBeanFactory().autowireBean(instance);
|
||||
}
|
||||
if (instance instanceof InitializingBean) {
|
||||
try {
|
||||
((InitializingBean) instance).afterPropertiesSet();
|
||||
} catch (Exception e) {
|
||||
throw new MappingException(e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
|
||||
return instance;
|
||||
}
|
||||
@@ -281,7 +285,7 @@ public class MappingMongoConverter implements MongoConverter, ApplicationContext
|
||||
}
|
||||
if (null != propertyObj) {
|
||||
if (prop.isComplexType()) {
|
||||
writeObjectInternal(prop, propertyObj, dbo);
|
||||
writePropertyInternal(prop, propertyObj, dbo);
|
||||
} else {
|
||||
dbo.put(name, propertyObj);
|
||||
}
|
||||
@@ -302,7 +306,7 @@ public class MappingMongoConverter implements MongoConverter, ApplicationContext
|
||||
throw new MappingException(e.getMessage(), e);
|
||||
}
|
||||
if (null != propertyObj) {
|
||||
writeObjectInternal(inverseProp, propertyObj, dbo);
|
||||
writePropertyInternal(inverseProp, propertyObj, dbo);
|
||||
}
|
||||
}
|
||||
});
|
||||
@@ -323,7 +327,7 @@ public class MappingMongoConverter implements MongoConverter, ApplicationContext
|
||||
}
|
||||
}
|
||||
|
||||
protected void writeObjectInternal(PersistentProperty<?> prop, Object obj, DBObject dbo) {
|
||||
protected void writePropertyInternal(PersistentProperty<?> prop, Object obj, DBObject dbo) {
|
||||
org.springframework.data.document.mongodb.mapping.DBRef dbref = prop.getField()
|
||||
.getAnnotation(org.springframework.data.document.mongodb.mapping.DBRef.class);
|
||||
String name = prop.getName();
|
||||
@@ -344,6 +348,10 @@ public class MappingMongoConverter implements MongoConverter, ApplicationContext
|
||||
}
|
||||
}
|
||||
dbo.put(name, dbList);
|
||||
} else if (null != obj && obj instanceof Map) {
|
||||
BasicDBObject mapDbObj = new BasicDBObject();
|
||||
writeMapInternal((Map<Object, Object>) obj, mapDbObj);
|
||||
dbo.put(name, mapDbObj);
|
||||
} else {
|
||||
if (null != dbref) {
|
||||
DBObject dbRefObj = createDBRef(obj, dbref);
|
||||
@@ -358,6 +366,26 @@ public class MappingMongoConverter implements MongoConverter, ApplicationContext
|
||||
}
|
||||
}
|
||||
|
||||
protected void writeMapInternal(Map<Object, Object> obj, DBObject dbo) {
|
||||
Set<String> simpleTypes = MappingBeanHelper.getSimpleTypes();
|
||||
for (Map.Entry<Object, Object> entry : obj.entrySet()) {
|
||||
Object key = entry.getKey();
|
||||
Object val = entry.getValue();
|
||||
if (simpleTypes.contains(key.getClass().getName())) {
|
||||
String simpleKey = conversionService.convert(key, String.class);
|
||||
if (simpleTypes.contains(val.getClass().toString())) {
|
||||
dbo.put(simpleKey, val);
|
||||
} else {
|
||||
DBObject newDbo = new BasicDBObject();
|
||||
write(val, newDbo);
|
||||
dbo.put(simpleKey, newDbo);
|
||||
}
|
||||
} else {
|
||||
throw new MappingException("Cannot use a complex object as a key value.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected DBObject createDBRef(Object target, org.springframework.data.document.mongodb.mapping.DBRef dbref) {
|
||||
PersistentEntity<?> targetEntity = mappingContext.getPersistentEntity(target.getClass());
|
||||
if (null == targetEntity || null == targetEntity.getIdProperty()) {
|
||||
@@ -404,7 +432,18 @@ public class MappingMongoConverter implements MongoConverter, ApplicationContext
|
||||
Object dbObj = from.get(name);
|
||||
if (dbObj instanceof DBObject) {
|
||||
Class<?> type = prop.getType();
|
||||
if (type.isArray() && dbObj instanceof BasicDBObject && ((DBObject) dbObj).keySet().size() == 0) {
|
||||
if (type.isAssignableFrom(Map.class) && dbObj instanceof DBObject) {
|
||||
Map m = new LinkedHashMap();
|
||||
for (Map.Entry<String, Object> entry : ((Map<String, Object>) ((DBObject) dbObj).toMap()).entrySet()) {
|
||||
if (null != entry.getValue()
|
||||
&& MappingBeanHelper.getSimpleTypes().contains(entry.getValue().getClass().getName())) {
|
||||
m.put(entry.getKey(), entry.getValue());
|
||||
} else if (null != entry.getValue()) {
|
||||
m.put(entry.getKey(), entry.getValue());
|
||||
}
|
||||
}
|
||||
return m;
|
||||
} else if (type.isArray() && dbObj instanceof BasicDBObject && ((DBObject) dbObj).keySet().size() == 0) {
|
||||
// It's empty
|
||||
return Array.newInstance(type.getComponentType(), 0);
|
||||
} else if (prop.isCollection() && dbObj instanceof BasicDBList) {
|
||||
|
||||
@@ -0,0 +1,47 @@
|
||||
/*
|
||||
* Copyright (c) 2011 by the original author(s).
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.data.document.mongodb.mapping;
|
||||
|
||||
/**
|
||||
* @author Jon Brisbin <jbrisbin@vmware.com>
|
||||
*/
|
||||
public class AccountPojo {
|
||||
|
||||
private String type;
|
||||
private Float balance;
|
||||
|
||||
public AccountPojo(String type, Float balance) {
|
||||
this.type = type;
|
||||
this.balance = balance;
|
||||
}
|
||||
|
||||
public String getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
public void setType(String type) {
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
public Float getBalance() {
|
||||
return balance;
|
||||
}
|
||||
|
||||
public void setBalance(Float balance) {
|
||||
this.balance = balance;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
/*
|
||||
* Copyright (c) 2011 by the original author(s).
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.data.document.mongodb.mapping;
|
||||
|
||||
/**
|
||||
* @author Jon Brisbin <jbrisbin@vmware.com>
|
||||
*/
|
||||
public class BasePerson {
|
||||
|
||||
private Integer ssn;
|
||||
private String firstName;
|
||||
private String lastName;
|
||||
|
||||
public BasePerson(Integer ssn, String firstName, String lastName) {
|
||||
this.ssn = ssn;
|
||||
this.firstName = firstName;
|
||||
this.lastName = lastName;
|
||||
}
|
||||
|
||||
public Integer getSsn() {
|
||||
return ssn;
|
||||
}
|
||||
|
||||
public void setSsn(Integer ssn) {
|
||||
this.ssn = ssn;
|
||||
}
|
||||
|
||||
public String getFirstName() {
|
||||
return firstName;
|
||||
}
|
||||
|
||||
public void setFirstName(String firstName) {
|
||||
this.firstName = firstName;
|
||||
}
|
||||
|
||||
public String getLastName() {
|
||||
return lastName;
|
||||
}
|
||||
|
||||
public void setLastName(String lastName) {
|
||||
this.lastName = lastName;
|
||||
}
|
||||
}
|
||||
@@ -22,7 +22,6 @@ import org.junit.rules.ExpectedException;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.data.document.mongodb.MongoTemplate;
|
||||
import org.springframework.data.document.mongodb.convert.MongoConverter;
|
||||
import org.springframework.data.document.mongodb.query.Criteria;
|
||||
import org.springframework.data.document.mongodb.query.Query;
|
||||
import org.springframework.data.mapping.BasicMappingContext;
|
||||
@@ -30,7 +29,9 @@ import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import static org.hamcrest.Matchers.is;
|
||||
import static org.hamcrest.Matchers.notNullValue;
|
||||
@@ -58,9 +59,47 @@ public class MappingTests {
|
||||
template.dropCollection("account");
|
||||
}
|
||||
|
||||
@SuppressWarnings({"unchecked"})
|
||||
@Test
|
||||
public void testWrite() {
|
||||
public void testPersonPojo() {
|
||||
PersonPojo p = new PersonPojo(12345, "Person", "Pojo");
|
||||
template.insert(p);
|
||||
|
||||
assertNotNull(p.getId());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPersonWithCustomIdName() {
|
||||
PersonCustomIdName p = new PersonCustomIdName(123456, "Custom", "Id");
|
||||
template.insert(p);
|
||||
|
||||
List<PersonCustomIdName> result = template.find(new Query(Criteria.where("ssn").is(123456)), PersonCustomIdName.class);
|
||||
assertThat(result.size(), is(1));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPersonMapProperty() {
|
||||
PersonMapProperty p = new PersonMapProperty(1234567, "Map", "Property");
|
||||
Map<String, AccountPojo> accounts = new HashMap<String, AccountPojo>();
|
||||
|
||||
AccountPojo checking = new AccountPojo("checking", 1000.0f);
|
||||
AccountPojo savings = new AccountPojo("savings", 10000.0f);
|
||||
|
||||
accounts.put("checking", checking);
|
||||
accounts.put("savings", savings);
|
||||
p.setAccounts(accounts);
|
||||
|
||||
template.insert(p);
|
||||
assertNotNull(p.getId());
|
||||
|
||||
List<PersonMapProperty> result = template.find(new Query(Criteria.where("ssn").is(1234567)), PersonMapProperty.class);
|
||||
assertThat(result.size(), is(1));
|
||||
assertThat(result.get(0).getAccounts().size(), is(2));
|
||||
assertNotNull(result.get(0).getAccounts().get("checking"));
|
||||
}
|
||||
|
||||
@Test
|
||||
@SuppressWarnings({"unchecked"})
|
||||
public void testWriteEntity() {
|
||||
Person p = new Person(123456789, "John", "Doe", 37);
|
||||
|
||||
Address addr = new Address();
|
||||
@@ -84,9 +123,7 @@ public class MappingTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRead() {
|
||||
MongoConverter converter = template.getConverter();
|
||||
|
||||
public void testReadEntity() {
|
||||
List<Person> result = template.find(new Query(Criteria.where("ssn").is(123456789)), Person.class);
|
||||
assertThat(result.size(), is(1));
|
||||
assertThat(result.get(0).getAddress().getCountry(), is("USA"));
|
||||
|
||||
@@ -16,9 +16,11 @@
|
||||
|
||||
package org.springframework.data.document.mongodb.mapping;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.data.annotation.Id;
|
||||
import org.springframework.data.annotation.PersistenceConstructor;
|
||||
import org.springframework.data.annotation.Transient;
|
||||
import org.springframework.data.document.mongodb.MongoTemplate;
|
||||
import org.springframework.data.document.mongodb.index.CompoundIndex;
|
||||
import org.springframework.data.document.mongodb.index.CompoundIndexes;
|
||||
import org.springframework.data.document.mongodb.index.Indexed;
|
||||
@@ -47,6 +49,8 @@ public class Person<T extends Address> {
|
||||
@DBRef
|
||||
private List<Account> accounts;
|
||||
private T address;
|
||||
@Autowired
|
||||
private MongoTemplate mongoTemplate;
|
||||
|
||||
public Person(Integer ssn, String firstName, String lastName, Integer age) {
|
||||
this.ssn = ssn;
|
||||
|
||||
@@ -0,0 +1,70 @@
|
||||
/*
|
||||
* Copyright (c) 2011 by the original author(s).
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.data.document.mongodb.mapping;
|
||||
|
||||
import org.bson.types.ObjectId;
|
||||
import org.springframework.data.annotation.Id;
|
||||
|
||||
/**
|
||||
* @author Jon Brisbin <jbrisbin@vmware.com>
|
||||
*/
|
||||
public class PersonCustomIdName {
|
||||
|
||||
@Id
|
||||
private ObjectId customId;
|
||||
private Integer ssn;
|
||||
private String firstName;
|
||||
private String lastName;
|
||||
|
||||
public PersonCustomIdName(Integer ssn, String firstName, String lastName) {
|
||||
this.ssn = ssn;
|
||||
this.firstName = firstName;
|
||||
this.lastName = lastName;
|
||||
}
|
||||
|
||||
public ObjectId getCustomId() {
|
||||
return customId;
|
||||
}
|
||||
|
||||
public void setCustomId(ObjectId customId) {
|
||||
this.customId = customId;
|
||||
}
|
||||
|
||||
public Integer getSsn() {
|
||||
return ssn;
|
||||
}
|
||||
|
||||
public void setSsn(Integer ssn) {
|
||||
this.ssn = ssn;
|
||||
}
|
||||
|
||||
public String getFirstName() {
|
||||
return firstName;
|
||||
}
|
||||
|
||||
public void setFirstName(String firstName) {
|
||||
this.firstName = firstName;
|
||||
}
|
||||
|
||||
public String getLastName() {
|
||||
return lastName;
|
||||
}
|
||||
|
||||
public void setLastName(String lastName) {
|
||||
this.lastName = lastName;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
/*
|
||||
* Copyright (c) 2011 by the original author(s).
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.data.document.mongodb.mapping;
|
||||
|
||||
import org.bson.types.ObjectId;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @author Jon Brisbin <jbrisbin@vmware.com>
|
||||
*/
|
||||
@Document
|
||||
public class PersonMapProperty extends BasePerson {
|
||||
|
||||
private ObjectId id;
|
||||
private Map<String, AccountPojo> accounts;
|
||||
|
||||
public PersonMapProperty(Integer ssn, String firstName, String lastName) {
|
||||
super(ssn, firstName, lastName);
|
||||
}
|
||||
|
||||
public ObjectId getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(ObjectId id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public Map<String, AccountPojo> getAccounts() {
|
||||
return accounts;
|
||||
}
|
||||
|
||||
public void setAccounts(Map<String, AccountPojo> accounts) {
|
||||
this.accounts = accounts;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
/*
|
||||
* Copyright (c) 2011 by the original author(s).
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.data.document.mongodb.mapping;
|
||||
|
||||
import org.bson.types.ObjectId;
|
||||
|
||||
/**
|
||||
* @author Jon Brisbin <jbrisbin@vmware.com>
|
||||
*/
|
||||
public class PersonPojo {
|
||||
|
||||
private ObjectId id;
|
||||
private Integer ssn;
|
||||
private String firstName;
|
||||
private String lastName;
|
||||
|
||||
public PersonPojo(Integer ssn, String firstName, String lastName) {
|
||||
this.ssn = ssn;
|
||||
this.firstName = firstName;
|
||||
this.lastName = lastName;
|
||||
}
|
||||
|
||||
public ObjectId getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(ObjectId id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public Integer getSsn() {
|
||||
return ssn;
|
||||
}
|
||||
|
||||
public void setSsn(Integer ssn) {
|
||||
this.ssn = ssn;
|
||||
}
|
||||
|
||||
public String getFirstName() {
|
||||
return firstName;
|
||||
}
|
||||
|
||||
public void setFirstName(String firstName) {
|
||||
this.firstName = firstName;
|
||||
}
|
||||
|
||||
public String getLastName() {
|
||||
return lastName;
|
||||
}
|
||||
|
||||
public void setLastName(String lastName) {
|
||||
this.lastName = lastName;
|
||||
}
|
||||
}
|
||||
@@ -8,6 +8,14 @@
|
||||
<property name="port" value="27017"/>
|
||||
</bean>
|
||||
|
||||
<bean id="mappingContext" class="org.springframework.data.mapping.BasicMappingContext">
|
||||
<property name="mappingConfigurationBuilder">
|
||||
<bean class="org.springframework.data.document.mongodb.mapping.MongoMappingConfigurationBuilder">
|
||||
<constructor-arg ref="mongoTemplate"/>
|
||||
</bean>
|
||||
</property>
|
||||
</bean>
|
||||
|
||||
<bean id="mongoConverter" class="org.springframework.data.document.mongodb.convert.MappingMongoConverter">
|
||||
<property name="mappingContext" ref="mappingContext"/>
|
||||
<property name="autowirePersistentBeans" value="true"/>
|
||||
@@ -20,14 +28,6 @@
|
||||
<constructor-arg ref="mongoConverter"/>
|
||||
</bean>
|
||||
|
||||
<bean id="mappingContext" class="org.springframework.data.mapping.BasicMappingContext">
|
||||
<property name="mappingConfigurationBuilder">
|
||||
<bean class="org.springframework.data.document.mongodb.mapping.MongoMappingConfigurationBuilder">
|
||||
<constructor-arg ref="mongoTemplate"/>
|
||||
</bean>
|
||||
</property>
|
||||
</bean>
|
||||
|
||||
<bean class="org.springframework.data.document.mongodb.MongoExceptionTranslator"/>
|
||||
|
||||
</beans>
|
||||
|
||||
Reference in New Issue
Block a user