From 236b808d0545114eabc98a9eb954f978ef032ecf Mon Sep 17 00:00:00 2001 From: coach88 Date: Sat, 15 Aug 2015 00:11:19 +0300 Subject: [PATCH] Minor cleanup with tests Added converter on saving in db user --- .../org/baeldung/annotation/CascadeSave.java | 12 ++++++ .../java/org/baeldung/config/MongoConfig.java | 15 ++++++++ .../converter/UserWriterConverter.java | 25 +++++++++++++ .../event/CascadingMongoEventListener.java | 37 +++++++++++++++++++ .../baeldung/event/DbRefFieldCallback.java | 22 +++++++++++ .../java/org/baeldung/model/EmailAddress.java | 34 +++++++++++++++++ .../main/java/org/baeldung/model/User.java | 12 +++++- .../MongoTemplateQueryIntegrationTest.java | 6 ++- .../repository/BaseQueryIntegrationTest.java | 4 +- .../UserRepositoryIntegrationTest.java | 7 ++-- 10 files changed, 167 insertions(+), 7 deletions(-) create mode 100644 spring-data-mongodb/src/main/java/org/baeldung/annotation/CascadeSave.java create mode 100644 spring-data-mongodb/src/main/java/org/baeldung/converter/UserWriterConverter.java create mode 100644 spring-data-mongodb/src/main/java/org/baeldung/event/CascadingMongoEventListener.java create mode 100644 spring-data-mongodb/src/main/java/org/baeldung/event/DbRefFieldCallback.java create mode 100644 spring-data-mongodb/src/main/java/org/baeldung/model/EmailAddress.java diff --git a/spring-data-mongodb/src/main/java/org/baeldung/annotation/CascadeSave.java b/spring-data-mongodb/src/main/java/org/baeldung/annotation/CascadeSave.java new file mode 100644 index 0000000000..9fba40245b --- /dev/null +++ b/spring-data-mongodb/src/main/java/org/baeldung/annotation/CascadeSave.java @@ -0,0 +1,12 @@ +package org.baeldung.annotation; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.FIELD) +public @interface CascadeSave { + +} diff --git a/spring-data-mongodb/src/main/java/org/baeldung/config/MongoConfig.java b/spring-data-mongodb/src/main/java/org/baeldung/config/MongoConfig.java index 7a789b1859..8433e67850 100644 --- a/spring-data-mongodb/src/main/java/org/baeldung/config/MongoConfig.java +++ b/spring-data-mongodb/src/main/java/org/baeldung/config/MongoConfig.java @@ -1,9 +1,16 @@ package org.baeldung.config; +import java.util.ArrayList; +import java.util.List; + + +import org.baeldung.converter.UserWriterConverter; import org.baeldung.event.CascadingMongoEventListener; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.data.mongodb.config.AbstractMongoConfiguration; +import org.springframework.data.mongodb.core.convert.CustomConversions; +import org.springframework.core.convert.converter.Converter; import org.springframework.data.mongodb.repository.config.EnableMongoRepositories; import com.mongodb.Mongo; @@ -13,6 +20,8 @@ import com.mongodb.MongoClient; @EnableMongoRepositories(basePackages = "org.baeldung.repository") public class MongoConfig extends AbstractMongoConfiguration { + private List> converters = new ArrayList>(); + @Override protected String getDatabaseName() { return "test"; @@ -32,4 +41,10 @@ public class MongoConfig extends AbstractMongoConfiguration { public CascadingMongoEventListener cascadingMongoEventListener(){ return new CascadingMongoEventListener(); } + + @Override + public CustomConversions customConversions() { + converters.add(new UserWriterConverter()); + return new CustomConversions(converters); + } } diff --git a/spring-data-mongodb/src/main/java/org/baeldung/converter/UserWriterConverter.java b/spring-data-mongodb/src/main/java/org/baeldung/converter/UserWriterConverter.java new file mode 100644 index 0000000000..18f2314c6b --- /dev/null +++ b/spring-data-mongodb/src/main/java/org/baeldung/converter/UserWriterConverter.java @@ -0,0 +1,25 @@ +package org.baeldung.converter; + +import org.springframework.stereotype.Component; +import org.baeldung.model.User; +import org.springframework.core.convert.converter.Converter; + +import com.mongodb.BasicDBObject; +import com.mongodb.DBObject; + +@Component +public class UserWriterConverter implements Converter { + @Override + public DBObject convert(User user) { + DBObject dbObject = new BasicDBObject(); + dbObject.put("name", user.getName()); + dbObject.put("age", user.getAge()); + if (user.getEmailAddress() != null) { + DBObject emailDbObject = new BasicDBObject(); + emailDbObject.put("value", user.getEmailAddress().getValue()); + dbObject.put("email", emailDbObject); + } + dbObject.removeField("_class"); + return dbObject; + } +} diff --git a/spring-data-mongodb/src/main/java/org/baeldung/event/CascadingMongoEventListener.java b/spring-data-mongodb/src/main/java/org/baeldung/event/CascadingMongoEventListener.java new file mode 100644 index 0000000000..e461160eb4 --- /dev/null +++ b/spring-data-mongodb/src/main/java/org/baeldung/event/CascadingMongoEventListener.java @@ -0,0 +1,37 @@ +package org.baeldung.event; + +import org.baeldung.annotation.CascadeSave; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.mongodb.core.MongoOperations; +import org.springframework.data.mongodb.core.mapping.DBRef; +import org.springframework.data.mongodb.core.mapping.event.AbstractMongoEventListener; +import org.springframework.util.ReflectionUtils; + +import java.lang.reflect.Field; + +public class CascadingMongoEventListener extends AbstractMongoEventListener { + @Autowired + private MongoOperations mongoOperations; + + @Override + public void onBeforeConvert(final Object source) { + ReflectionUtils.doWithFields(source.getClass(), new ReflectionUtils.FieldCallback() { + + public void doWith(Field field) throws IllegalArgumentException, IllegalAccessException { + ReflectionUtils.makeAccessible(field); + + if (field.isAnnotationPresent(DBRef.class) && field.isAnnotationPresent(CascadeSave.class)) { + final Object fieldValue = field.get(source); + + if (fieldValue != null) { + DbRefFieldCallback callback = new DbRefFieldCallback(); + + ReflectionUtils.doWithFields(fieldValue.getClass(), callback); + + mongoOperations.save(fieldValue); + } + } + } + }); + } +} diff --git a/spring-data-mongodb/src/main/java/org/baeldung/event/DbRefFieldCallback.java b/spring-data-mongodb/src/main/java/org/baeldung/event/DbRefFieldCallback.java new file mode 100644 index 0000000000..66f797042a --- /dev/null +++ b/spring-data-mongodb/src/main/java/org/baeldung/event/DbRefFieldCallback.java @@ -0,0 +1,22 @@ +package org.baeldung.event; + +import java.lang.reflect.Field; + +import org.springframework.data.annotation.Id; +import org.springframework.util.ReflectionUtils; + +public class DbRefFieldCallback implements ReflectionUtils.FieldCallback { + private boolean idFound; + + public void doWith(Field field) throws IllegalArgumentException, IllegalAccessException { + ReflectionUtils.makeAccessible(field); + + if (field.isAnnotationPresent(Id.class)) { + idFound = true; + } + } + + public boolean isIdFound() { + return idFound; + } +} diff --git a/spring-data-mongodb/src/main/java/org/baeldung/model/EmailAddress.java b/spring-data-mongodb/src/main/java/org/baeldung/model/EmailAddress.java new file mode 100644 index 0000000000..f54aea0e78 --- /dev/null +++ b/spring-data-mongodb/src/main/java/org/baeldung/model/EmailAddress.java @@ -0,0 +1,34 @@ +package org.baeldung.model; + +import org.springframework.data.annotation.Id; +import org.springframework.data.mongodb.core.mapping.Document; + +@Document +public class EmailAddress { + @Id + private String id; + private String value; + + public EmailAddress(){ + } + + public EmailAddress(String value) { + this.value = value; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getValue() { + return value; + } + + public void setValue(String value) { + this.value = value; + } +} diff --git a/spring-data-mongodb/src/main/java/org/baeldung/model/User.java b/spring-data-mongodb/src/main/java/org/baeldung/model/User.java index 77d53ffbe9..ff4eacd0c2 100644 --- a/spring-data-mongodb/src/main/java/org/baeldung/model/User.java +++ b/spring-data-mongodb/src/main/java/org/baeldung/model/User.java @@ -20,11 +20,21 @@ public class User { private String name; private Integer age; + @DBRef @Field("email") @CascadeSave - private EmailAddress emailAddress; + + public User(){ + } + + + public User(String name, Integer age, String value){ + this.name = name; + this.age = age; + this.emailAddress = new EmailAddress(value); + } public String getId() { return id; diff --git a/spring-data-mongodb/src/test/java/org/baeldung/mongotemplate/MongoTemplateQueryIntegrationTest.java b/spring-data-mongodb/src/test/java/org/baeldung/mongotemplate/MongoTemplateQueryIntegrationTest.java index 71ec9277b5..c23e981294 100644 --- a/spring-data-mongodb/src/test/java/org/baeldung/mongotemplate/MongoTemplateQueryIntegrationTest.java +++ b/spring-data-mongodb/src/test/java/org/baeldung/mongotemplate/MongoTemplateQueryIntegrationTest.java @@ -34,7 +34,9 @@ public class MongoTemplateQueryIntegrationTest { @Before public void testSetup() { - mongoTemplate.createCollection(User.class); + if (!mongoTemplate.collectionExists(User.class)) { + mongoTemplate.createCollection(User.class); + } } @After @@ -148,7 +150,7 @@ public class MongoTemplateQueryIntegrationTest { } @Test - public void givenExisted() { + public void whenSavingUserWithEmailAddress_thenUserandEmailAddressSaved() { User user = new User(); user.setName("Brendan"); EmailAddress emailAddress = new EmailAddress(); diff --git a/spring-data-mongodb/src/test/java/org/baeldung/repository/BaseQueryIntegrationTest.java b/spring-data-mongodb/src/test/java/org/baeldung/repository/BaseQueryIntegrationTest.java index 459716c7ca..8572cc858e 100644 --- a/spring-data-mongodb/src/test/java/org/baeldung/repository/BaseQueryIntegrationTest.java +++ b/spring-data-mongodb/src/test/java/org/baeldung/repository/BaseQueryIntegrationTest.java @@ -17,7 +17,9 @@ public class BaseQueryIntegrationTest { @Before public void testSetup() { - mongoOps.createCollection(User.class); + if (!mongoOps.collectionExists(User.class)) { + mongoOps.createCollection(User.class); + } } @After diff --git a/spring-data-mongodb/src/test/java/org/baeldung/repository/UserRepositoryIntegrationTest.java b/spring-data-mongodb/src/test/java/org/baeldung/repository/UserRepositoryIntegrationTest.java index 7524aacda2..53cadc09bc 100644 --- a/spring-data-mongodb/src/test/java/org/baeldung/repository/UserRepositoryIntegrationTest.java +++ b/spring-data-mongodb/src/test/java/org/baeldung/repository/UserRepositoryIntegrationTest.java @@ -34,7 +34,9 @@ public class UserRepositoryIntegrationTest { @Before public void testSetup() { - mongoOps.createCollection(User.class); + if (!mongoOps.collectionExists(User.class)) { + mongoOps.createCollection(User.class); + } } @After @@ -67,12 +69,11 @@ public class UserRepositoryIntegrationTest { mongoOps.insert(user); user = mongoOps.findOne(Query.query(Criteria.where("name").is("Jack")), User.class); - final String id = user.getId(); user.setName("Jim"); userRepository.save(user); - assertThat(mongoOps.findOne(Query.query(Criteria.where("id").is(id)), User.class).getName(), is("Jim")); + assertThat(mongoOps.findAll(User.class).size(), is(2)); } @Test