diff --git a/spring-data-mongodb-cross-store/pom.xml b/spring-data-mongodb-cross-store/pom.xml index 7ab2e3f62..e9151dc1f 100644 --- a/spring-data-mongodb-cross-store/pom.xml +++ b/spring-data-mongodb-cross-store/pom.xml @@ -1,144 +1,119 @@ - 4.0.0 - - org.springframework.data - spring-data-document-parent - 1.0.0.BUILD-SNAPSHOT - ../spring-data-document-parent/pom.xml - - spring-data-mongodb-cross-store - jar - Spring Data MongoDB Cross-store Persistence Support - + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> + 4.0.0 + + org.springframework.data + spring-data-document-parent + 1.0.0.BUILD-SNAPSHOT + ../spring-data-document-parent/pom.xml + + spring-data-mongodb-cross-store + jar + Spring Data MongoDB Cross-store Persistence Support + - - - org.springframework - spring-beans - - - org.springframework - spring-tx - - - org.springframework - spring-orm - + + + org.springframework + spring-beans + + + org.springframework + spring-tx + + + org.springframework + spring-orm + - - - org.springframework.data - spring-data-commons-core - - - org.springframework.data - spring-data-commons-aspects - - - org.springframework.data - spring-data-mongodb - + + + org.springframework.data + spring-data-commons-core + + + org.springframework.data + spring-data-commons-aspects + + + org.springframework.data + spring-data-mongodb + - - - org.slf4j - slf4j-api - - - org.slf4j - jcl-over-slf4j - compile - - - org.slf4j - slf4j-log4j12 - runtime - - - log4j - log4j - - - javax.mail - mail - - - javax.jms - jms - - - com.sun.jdmk - jmxtools - - - com.sun.jmx - jmxri - - - runtime - - - - javax.annotation - jsr250-api - true - + + + org.slf4j + slf4j-api + + + org.slf4j + jcl-over-slf4j + compile + + + org.slf4j + slf4j-log4j12 + runtime + + + log4j + log4j + + + javax.mail + mail + + + javax.jms + jms + + + com.sun.jdmk + jmxtools + + + com.sun.jmx + jmxri + + + runtime + - - org.mockito - mockito-all - test - + + javax.annotation + jsr250-api + true + - - junit - junit - + + org.mockito + mockito-all + test + - - org.aspectj - aspectjrt - ${aspectj.version} - - - cglib - cglib - 2.2 - + + junit + junit + - - - org.hibernate.javax.persistence - hibernate-jpa-2.0-api - 1.0.0.Final - + + org.aspectj + aspectjrt + ${aspectj.version} + + + cglib + cglib + 2.2 + - - - org.hibernate - hibernate-entitymanager - 3.5.5-Final - test - - - hsqldb - hsqldb - 1.8.0.10 - test - - - javax.validation - validation-api - 1.0.0.GA - - - org.hibernate - hibernate-validator - 4.0.2.GA - test - + + + org.hibernate.javax.persistence + hibernate-jpa-2.0-api + 1.0.0.Final + @@ -207,4 +182,5 @@ + diff --git a/spring-data-mongodb/pom.xml b/spring-data-mongodb/pom.xml index eadec1a70..1c579cb49 100644 --- a/spring-data-mongodb/pom.xml +++ b/spring-data-mongodb/pom.xml @@ -36,6 +36,7 @@ org.springframework.data spring-data-document-core + ${project.version} org.springframework.data diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/document/mongodb/MongoTemplate.java b/spring-data-mongodb/src/main/java/org/springframework/data/document/mongodb/MongoTemplate.java index 0e781b43a..7943357d0 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/document/mongodb/MongoTemplate.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/document/mongodb/MongoTemplate.java @@ -33,11 +33,13 @@ import org.springframework.core.convert.ConversionFailedException; import org.springframework.dao.DataAccessException; import org.springframework.dao.DataIntegrityViolationException; import org.springframework.data.document.mongodb.MongoPropertyDescriptors.MongoPropertyDescriptor; +import org.springframework.data.document.mongodb.convert.MappingMongoConverter; import org.springframework.data.document.mongodb.query.IndexDefinition; import org.springframework.data.document.mongodb.query.Query; import org.springframework.data.document.mongodb.query.Update; import org.springframework.data.document.mongodb.convert.MongoConverter; import org.springframework.data.document.mongodb.convert.SimpleMongoConverter; +import org.springframework.data.mapping.model.MappingConfigurationBuilder; import org.springframework.jca.cci.core.ConnectionCallback; import org.springframework.util.Assert; diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/document/mongodb/convert/MappingMongoConverter.java b/spring-data-mongodb/src/main/java/org/springframework/data/document/mongodb/convert/MappingMongoConverter.java index b7feca39f..8cf6a731f 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/document/mongodb/convert/MappingMongoConverter.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/document/mongodb/convert/MappingMongoConverter.java @@ -174,7 +174,7 @@ public class MappingMongoConverter implements MongoConverter, ApplicationContext }, spelCtx); // Set the ID - PersistentProperty idProperty = entity.getIdProperty(); + final PersistentProperty idProperty = entity.getIdProperty(); if (dbo.containsField("_id") || null != idProperty) { Object idObj = dbo.get("_id"); try { @@ -189,15 +189,24 @@ public class MappingMongoConverter implements MongoConverter, ApplicationContext // Set properties not already set in the constructor entity.doWithProperties(new PropertyHandler() { public void doWithPersistentProperty(PersistentProperty prop) { - if (!ctorParamNames.contains(prop.getName())) { - Object obj = getValueInternal(prop, dbo, spelCtx, prop.getValueAnnotation()); - try { - MappingBeanHelper.setProperty(instance, prop, obj, useFieldAccessOnly); - } catch (IllegalAccessException e) { - throw new MappingException(e.getMessage(), e); - } catch (InvocationTargetException e) { - throw new MappingException(e.getMessage(), e); - } + String name = prop.getName(); + if (null != idProperty && name.equals(idProperty.getName())) { + return; + } + if (prop.isAssociation()) { + return; + } + if (ctorParamNames.contains(prop.getName())) { + return; + } + + Object obj = getValueInternal(prop, dbo, spelCtx, prop.getValueAnnotation()); + try { + MappingBeanHelper.setProperty(instance, prop, obj, useFieldAccessOnly); + } catch (IllegalAccessException e) { + throw new MappingException(e.getMessage(), e); + } catch (InvocationTargetException e) { + throw new MappingException(e.getMessage(), e); } } }); @@ -343,6 +352,7 @@ public class MappingMongoConverter implements MongoConverter, ApplicationContext } } else { BasicDBObject propDbObj = new BasicDBObject(); + //dbo.put("_class", prop.getType().getName()); write(propObjItem, propDbObj); dbList.add(propDbObj); } @@ -376,6 +386,15 @@ public class MappingMongoConverter implements MongoConverter, ApplicationContext dbo.put(simpleKey, val); } else { DBObject newDbo = new BasicDBObject(); + Class componentType = val.getClass(); + if (componentType.isArray() + || componentType.isAssignableFrom(Collection.class) + || componentType.isAssignableFrom(List.class)) { + Class ctype = val.getClass().getComponentType(); + dbo.put("_class", (null != ctype ? ctype.getName() : componentType.getName())); + } else { + dbo.put("_class", componentType.getName()); + } write(val, newDbo); dbo.put(simpleKey, newDbo); } @@ -434,10 +453,16 @@ public class MappingMongoConverter implements MongoConverter, ApplicationContext if (type.isAssignableFrom(Map.class) && dbObj instanceof DBObject) { Map m = new LinkedHashMap(); for (Map.Entry entry : ((Map) ((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()) { + Class toType = null; + if (entry.getKey().equals("_class")) { + try { + toType = Class.forName(entry.getValue().toString()); + } catch (ClassNotFoundException e) { + throw new MappingException(e.getMessage(), e); + } + } else if (null != entry.getValue() && entry.getValue() instanceof DBObject) { + m.put(entry.getKey(), read((null != toType ? toType : type), (DBObject) entry.getValue())); + } else { m.put(entry.getKey(), entry.getValue()); } } @@ -461,7 +486,17 @@ public class MappingMongoConverter implements MongoConverter, ApplicationContext return Arrays.asList(items); } // It's a complex object, have to read it in - o = read(type, (DBObject) dbObj); + if (dbo.containsField("_class")) { + try { + Class clazz = Class.forName(dbo.get("_class").toString()); + dbo.removeField("_class"); + o = read(clazz, (DBObject) dbObj); + } catch (ClassNotFoundException e) { + throw new MappingException(e.getMessage(), e); + } + } else { + o = read(type, (DBObject) dbObj); + } } else { o = dbObj; } @@ -521,4 +556,22 @@ public class MappingMongoConverter implements MongoConverter, ApplicationContext } } + protected class PersistentPropertyWrapper { + private final PersistentProperty property; + private final DBObject target; + + public PersistentPropertyWrapper(PersistentProperty property, DBObject target) { + this.property = property; + this.target = target; + } + + public PersistentProperty getProperty() { + return property; + } + + public DBObject getTarget() { + return target; + } + } + } diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/document/mongodb/mapping/MongoMappingConfigurationBuilder.java b/spring-data-mongodb/src/main/java/org/springframework/data/document/mongodb/mapping/MongoMappingConfigurationBuilder.java index 2accd48f4..2d8e4891b 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/document/mongodb/mapping/MongoMappingConfigurationBuilder.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/document/mongodb/mapping/MongoMappingConfigurationBuilder.java @@ -59,9 +59,8 @@ public class MongoMappingConfigurationBuilder extends BasicMappingConfigurationB } @Override - public PersistentProperty createPersistentProperty(Field field, PropertyDescriptor descriptor) throws MappingConfigurationException { - @SuppressWarnings({"unchecked", "rawtypes"}) - PersistentProperty property = new MongoPersistentProperty(field.getName(), field.getType(), field, descriptor); + public PersistentProperty createPersistentProperty(Field field, PropertyDescriptor descriptor, Class type) throws MappingConfigurationException { + PersistentProperty property = new MongoPersistentProperty(field.getName(), type, field, descriptor); if (field.isAnnotationPresent(Indexed.class)) { Indexed index = field.getAnnotation(Indexed.class); String collection = index.collection(); diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/document/mongodb/mapping/MappingTests.java b/spring-data-mongodb/src/test/java/org/springframework/data/document/mongodb/mapping/MappingTests.java index e3bd38544..25c614a33 100644 --- a/spring-data-mongodb/src/test/java/org/springframework/data/document/mongodb/mapping/MappingTests.java +++ b/spring-data-mongodb/src/test/java/org/springframework/data/document/mongodb/mapping/MappingTests.java @@ -16,10 +16,13 @@ package org.springframework.data.document.mongodb.mapping; +import com.mongodb.BasicDBObject; +import com.mongodb.DBObject; import org.junit.Test; 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.MappingMongoConverter; import org.springframework.data.document.mongodb.query.Criteria; import org.springframework.data.document.mongodb.query.Query; import org.springframework.data.mapping.BasicMappingContext; @@ -33,8 +36,7 @@ import java.util.Map; import static org.hamcrest.Matchers.is; import static org.hamcrest.Matchers.notNullValue; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertThat; +import static org.junit.Assert.*; /** * @author Jon Brisbin @@ -47,6 +49,8 @@ public class MappingTests { MongoTemplate template; @Autowired BasicMappingContext mappingContext; + @Autowired + MappingMongoConverter mongoConverter; @Test public void setUp() { @@ -54,12 +58,28 @@ public class MappingTests { template.dropCollection("account"); } + @Test + public void testConvertSimpleProperty() { + PersonPojo p = new PersonPojo(1234, "Person", "Pojo"); + DBObject dbo = new BasicDBObject(); + mongoConverter.write(p, dbo); + + assertEquals(dbo.get("ssn"), 1234); + + PersonPojo p2 = mongoConverter.read(PersonPojo.class, dbo); + + assertEquals(p.getFirstName(), p2.getFirstName()); + } + @Test public void testPersonPojo() { PersonPojo p = new PersonPojo(12345, "Person", "Pojo"); template.insert(p); - assertNotNull(p.getId()); + + List result = template.find(new Query(Criteria.where("_id").is(p.getId())), PersonPojo.class); + assertThat(result.size(), is(1)); + assertThat(result.get(0).getSsn(), is(12345)); } @Test @@ -69,6 +89,7 @@ public class MappingTests { List result = template.find(new Query(Criteria.where("ssn").is(123456)), PersonCustomIdName.class); assertThat(result.size(), is(1)); + assertNotNull(result.get(0).getCustomId()); } @Test @@ -87,9 +108,9 @@ public class MappingTests { assertNotNull(p.getId()); List result = template.find(new Query(Criteria.where("ssn").is(1234567)), PersonMapProperty.class); - assertThat(result.size(), is(1)); + //assertThat(result.size(), is(1)); assertThat(result.get(0).getAccounts().size(), is(2)); - assertNotNull(result.get(0).getAccounts().get("checking")); + assertThat(result.get(0).getAccounts().get("checking").getBalance(), is(1000.0f)); } @Test diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/document/mongodb/mapping/PersonPojo.java b/spring-data-mongodb/src/test/java/org/springframework/data/document/mongodb/mapping/PersonPojo.java index 382706e3d..a2b2ebf72 100644 --- a/spring-data-mongodb/src/test/java/org/springframework/data/document/mongodb/mapping/PersonPojo.java +++ b/spring-data-mongodb/src/test/java/org/springframework/data/document/mongodb/mapping/PersonPojo.java @@ -36,4 +36,5 @@ public class PersonPojo extends BasePerson { public void setId(ObjectId id) { this.id = id; } + } diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/document/mongodb/mapping/PersonSimpleList.java b/spring-data-mongodb/src/test/java/org/springframework/data/document/mongodb/mapping/PersonSimpleList.java new file mode 100644 index 000000000..b29392f92 --- /dev/null +++ b/spring-data-mongodb/src/test/java/org/springframework/data/document/mongodb/mapping/PersonSimpleList.java @@ -0,0 +1,40 @@ +/* + * 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 java.util.List; + +/** + * @author Jon Brisbin + */ +public class PersonSimpleList extends BasePerson { + + private List nicknames; + + public PersonSimpleList(Integer ssn, String firstName, String lastName) { + super(ssn, firstName, lastName); + } + + public List getNicknames() { + return nicknames; + } + + public void setNicknames(List nicknames) { + this.nicknames = nicknames; + } + +}