Merge pull request #236 from alex-semenyuk/master
Introduction to Spring Data MongoDB (continue)
This commit is contained in:
commit
393c1eac14
|
@ -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 {
|
||||
|
||||
}
|
|
@ -1,7 +1,15 @@
|
|||
package org.baeldung.config;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.baeldung.converter.UserWriterConverter;
|
||||
import org.baeldung.event.CascadeSaveMongoEventListener;
|
||||
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;
|
||||
|
@ -11,6 +19,8 @@ import com.mongodb.MongoClient;
|
|||
@EnableMongoRepositories(basePackages = "org.baeldung.repository")
|
||||
public class MongoConfig extends AbstractMongoConfiguration {
|
||||
|
||||
private List<Converter<?, ?>> converters = new ArrayList<Converter<?, ?>>();
|
||||
|
||||
@Override
|
||||
protected String getDatabaseName() {
|
||||
return "test";
|
||||
|
@ -25,4 +35,15 @@ public class MongoConfig extends AbstractMongoConfiguration {
|
|||
public String getMappingBasePackage() {
|
||||
return "org.baeldung";
|
||||
}
|
||||
|
||||
@Bean
|
||||
public CascadeSaveMongoEventListener cascadingMongoEventListener() {
|
||||
return new CascadeSaveMongoEventListener();
|
||||
}
|
||||
|
||||
@Override
|
||||
public CustomConversions customConversions() {
|
||||
converters.add(new UserWriterConverter());
|
||||
return new CustomConversions(converters);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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<User, DBObject> {
|
||||
@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;
|
||||
}
|
||||
}
|
|
@ -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 CascadeSaveMongoEventListener extends AbstractMongoEventListener<Object> {
|
||||
@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) {
|
||||
FieldCallback callback = new FieldCallback();
|
||||
|
||||
ReflectionUtils.doWithFields(fieldValue.getClass(), callback);
|
||||
|
||||
mongoOperations.save(fieldValue);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
|
@ -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 FieldCallback 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;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,27 @@
|
|||
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 String getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(final String id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
public void setValue(final String value) {
|
||||
this.value = value;
|
||||
}
|
||||
}
|
|
@ -1,7 +1,12 @@
|
|||
package org.baeldung.model;
|
||||
|
||||
import org.baeldung.annotation.CascadeSave;
|
||||
import org.springframework.data.annotation.Id;
|
||||
import org.springframework.data.mongodb.core.index.IndexDirection;
|
||||
import org.springframework.data.mongodb.core.index.Indexed;
|
||||
import org.springframework.data.mongodb.core.mapping.DBRef;
|
||||
import org.springframework.data.mongodb.core.mapping.Document;
|
||||
import org.springframework.data.mongodb.core.mapping.Field;
|
||||
|
||||
import com.mysema.query.annotations.QueryEntity;
|
||||
|
||||
|
@ -11,9 +16,16 @@ public class User {
|
|||
|
||||
@Id
|
||||
private String id;
|
||||
@Indexed(direction = IndexDirection.ASCENDING)
|
||||
private String name;
|
||||
|
||||
private Integer age;
|
||||
|
||||
@DBRef
|
||||
@Field("email")
|
||||
@CascadeSave
|
||||
private EmailAddress emailAddress;
|
||||
|
||||
public String getId() {
|
||||
return id;
|
||||
}
|
||||
|
@ -37,4 +49,12 @@ public class User {
|
|||
public void setAge(final Integer age) {
|
||||
this.age = age;
|
||||
}
|
||||
|
||||
public EmailAddress getEmailAddress() {
|
||||
return emailAddress;
|
||||
}
|
||||
|
||||
public void setEmailAddress(EmailAddress emailAddress) {
|
||||
this.emailAddress = emailAddress;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
|
||||
<bean id="mongoTemplate" class="org.springframework.data.mongodb.core.MongoTemplate">
|
||||
<constructor-arg name="mongo" ref="mongo"/>
|
||||
<constructor-arg ref="mongoConverter" />
|
||||
<constructor-arg name="databaseName" value="test"/>
|
||||
</bean>
|
||||
|
||||
|
@ -24,7 +25,11 @@
|
|||
|
||||
<mongo:repositories base-package="org.baeldung.repository" mongo-template-ref="mongoTemplate"/>
|
||||
|
||||
<bean class="org.baeldung.event.BeforeConvertListener">
|
||||
<bean class="org.baeldung.event.CascadeSaveMongoEventListener">
|
||||
</bean>
|
||||
|
||||
<mongo:mapping-converter id="mongoConverter" base-package="org.baeldung.converter">
|
||||
<mongo:custom-converters base-package="org.baeldung.converter"/>
|
||||
</mongo:mapping-converter>
|
||||
|
||||
</beans>
|
|
@ -7,6 +7,7 @@ import java.util.Iterator;
|
|||
import java.util.List;
|
||||
|
||||
import org.baeldung.config.MongoConfig;
|
||||
import org.baeldung.model.EmailAddress;
|
||||
import org.baeldung.model.User;
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
|
@ -31,11 +32,14 @@ public class DocumentQueryIntegrationTest {
|
|||
|
||||
@Before
|
||||
public void testSetup() {
|
||||
if (!mongoTemplate.collectionExists(User.class)) {
|
||||
mongoTemplate.createCollection(User.class);
|
||||
}
|
||||
}
|
||||
|
||||
@After
|
||||
public void tearDown() {
|
||||
mongoTemplate.dropCollection(EmailAddress.class);
|
||||
mongoTemplate.dropCollection(User.class);
|
||||
}
|
||||
|
||||
|
|
|
@ -6,6 +6,7 @@ import static org.junit.Assert.assertThat;
|
|||
import java.util.List;
|
||||
|
||||
import org.baeldung.config.MongoConfig;
|
||||
import org.baeldung.model.EmailAddress;
|
||||
import org.baeldung.model.User;
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
|
@ -15,7 +16,10 @@ import org.springframework.beans.factory.annotation.Autowired;
|
|||
import org.springframework.data.domain.PageRequest;
|
||||
import org.springframework.data.domain.Pageable;
|
||||
import org.springframework.data.domain.Sort;
|
||||
import org.springframework.data.domain.Sort.Direction;
|
||||
import org.springframework.data.mongodb.core.MongoTemplate;
|
||||
import org.springframework.data.mongodb.core.index.Index;
|
||||
import org.springframework.data.mongodb.core.index.IndexInfo;
|
||||
import org.springframework.data.mongodb.core.query.Criteria;
|
||||
import org.springframework.data.mongodb.core.query.Query;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
|
@ -30,8 +34,10 @@ public class MongoTemplateQueryIntegrationTest {
|
|||
|
||||
@Before
|
||||
public void testSetup() {
|
||||
if (!mongoTemplate.collectionExists(User.class)) {
|
||||
mongoTemplate.createCollection(User.class);
|
||||
}
|
||||
}
|
||||
|
||||
@After
|
||||
public void tearDown() {
|
||||
|
@ -128,4 +134,42 @@ public class MongoTemplateQueryIntegrationTest {
|
|||
List<User> users = mongoTemplate.find(query, User.class);
|
||||
assertThat(users.size(), is(3));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenUserExistsWithIndexAddedFromMapping_whenCheckingIndex_thenIndexIsExisted() {
|
||||
final User user = new User();
|
||||
user.setName("Brendan");
|
||||
EmailAddress emailAddress = new EmailAddress();
|
||||
emailAddress.setValue("a@gmail.com");
|
||||
user.setEmailAddress(emailAddress);
|
||||
mongoTemplate.insert(user);
|
||||
|
||||
List<IndexInfo> indexInfos = mongoTemplate.indexOps("user").getIndexInfo();
|
||||
|
||||
assertThat(indexInfos.size(), is(1));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenSavingUserWithEmailAddress_thenUserandEmailAddressSaved() {
|
||||
final User user = new User();
|
||||
user.setName("Brendan");
|
||||
EmailAddress emailAddress = new EmailAddress();
|
||||
emailAddress.setValue("b@gmail.com");
|
||||
user.setEmailAddress(emailAddress);
|
||||
mongoTemplate.insert(user);
|
||||
|
||||
assertThat(mongoTemplate.findOne(Query.query(Criteria.where("name").is("Brendan")), User.class).getEmailAddress().getValue(), is("b@gmail.com"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenUserExistsWithIndexAddedFromCode_whenCheckingIndex_thenIndexIsExisted() {
|
||||
final User user = new User();
|
||||
user.setName("Brendan");
|
||||
mongoTemplate.indexOps(User.class).ensureIndex(new Index().on("name", Direction.ASC));
|
||||
mongoTemplate.insert(user);
|
||||
|
||||
List<IndexInfo> indexInfos = mongoTemplate.indexOps("user").getIndexInfo();
|
||||
|
||||
assertThat(indexInfos.size(), is(2));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -17,8 +17,10 @@ public class BaseQueryIntegrationTest {
|
|||
|
||||
@Before
|
||||
public void testSetup() {
|
||||
if (!mongoOps.collectionExists(User.class)) {
|
||||
mongoOps.createCollection(User.class);
|
||||
}
|
||||
}
|
||||
|
||||
@After
|
||||
public void tearDown() {
|
||||
|
|
|
@ -34,8 +34,10 @@ public class UserRepositoryIntegrationTest {
|
|||
|
||||
@Before
|
||||
public void testSetup() {
|
||||
if (!mongoOps.collectionExists(User.class)) {
|
||||
mongoOps.createCollection(User.class);
|
||||
}
|
||||
}
|
||||
|
||||
@After
|
||||
public void tearDown() {
|
||||
|
@ -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
|
||||
|
@ -145,4 +146,5 @@ public class UserRepositoryIntegrationTest {
|
|||
assertThat(users.size(), is(1));
|
||||
assertThat(page.getTotalPages(), is(2));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue