Skip to content

DATAMONGO-1054 - Add support for fast insertion via MongoRepository.insert(..). #253

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 3 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

<groupId>org.springframework.data</groupId>
<artifactId>spring-data-mongodb-parent</artifactId>
<version>1.7.0.BUILD-SNAPSHOT</version>
<version>1.7.0.DATAMONGO-1054-SNAPSHOT</version>
<packaging>pom</packaging>

<name>Spring Data MongoDB</name>
Expand Down
4 changes: 2 additions & 2 deletions spring-data-mongodb-cross-store/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
<parent>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-mongodb-parent</artifactId>
<version>1.7.0.BUILD-SNAPSHOT</version>
<version>1.7.0.DATAMONGO-1054-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

Expand Down Expand Up @@ -48,7 +48,7 @@
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-mongodb</artifactId>
<version>1.7.0.BUILD-SNAPSHOT</version>
<version>1.7.0.DATAMONGO-1054-SNAPSHOT</version>
</dependency>

<dependency>
Expand Down
2 changes: 1 addition & 1 deletion spring-data-mongodb-distribution/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
<parent>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-mongodb-parent</artifactId>
<version>1.7.0.BUILD-SNAPSHOT</version>
<version>1.7.0.DATAMONGO-1054-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

Expand Down
2 changes: 1 addition & 1 deletion spring-data-mongodb-log4j/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
<parent>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-mongodb-parent</artifactId>
<version>1.7.0.BUILD-SNAPSHOT</version>
<version>1.7.0.DATAMONGO-1054-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

Expand Down
2 changes: 1 addition & 1 deletion spring-data-mongodb/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
<parent>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-mongodb-parent</artifactId>
<version>1.7.0.BUILD-SNAPSHOT</version>
<version>1.7.0.DATAMONGO-1054-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
*
* @author Oliver Gierke
* @author Christoph Strobl
* @author Thomas Darimont
*/
@NoRepositoryBean
public interface MongoRepository<T, ID extends Serializable> extends PagingAndSortingRepository<T, ID> {
Expand All @@ -48,4 +49,30 @@ public interface MongoRepository<T, ID extends Serializable> extends PagingAndSo
* @see org.springframework.data.repository.PagingAndSortingRepository#findAll(org.springframework.data.domain.Sort)
*/
List<T> findAll(Sort sort);

/**
* Saves a given entity. Use the returned instance for further operations as the save operation might have changed the
* entity instance completely.
* <p>
* This uses {@link org.springframework.data.mongodb.core.MongoTemplate#insert(Object)} for storing the given entity.
* <p>
* Note that this method does neither fire any save events nor performs any id population or version checking.
*
* @param entity
* @return the saved entity
*/
<S extends T> S insert(S entity);

/**
* Saves all given entities.
* <p>
* This uses {@link org.springframework.data.mongodb.core.MongoTemplate#insert(Object)} for storing the given entity.
* <p>
* Note that this method does neither fire any save events nor nor performs any id population or version checking.
*
* @param entities
* @return the saved entities
* @throws IllegalArgumentException in case the given entity is (@literal null}.
*/
<S extends T> List<S> insert(Iterable<S> entities);
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
Expand All @@ -41,14 +42,15 @@
*
* @author Oliver Gierke
* @author Christoph Strobl
* @author Thomas Darimont
*/
public class SimpleMongoRepository<T, ID extends Serializable> implements MongoRepository<T, ID> {

private final MongoOperations mongoOperations;
private final MongoEntityInformation<T, ID> entityInformation;

/**
* Creates a ew {@link SimpleMongoRepository} for the given {@link MongoEntityInformation} and {@link MongoTemplate}.
* Creates a new {@link SimpleMongoRepository} for the given {@link MongoEntityInformation} and {@link MongoTemplate}.
*
* @param metadata must not be {@literal null}.
* @param template must not be {@literal null}.
Expand Down Expand Up @@ -82,7 +84,7 @@ public <S extends T> List<S> save(Iterable<S> entities) {

Assert.notNull(entities, "The given Iterable of entities not be null!");

List<S> result = new ArrayList<S>();
List<S> result = new ArrayList<S>(tryDetermineRealSizeOrReturn(entities, 10));

for (S entity : entities) {
save(entity);
Expand Down Expand Up @@ -181,7 +183,7 @@ public List<T> findAll() {
*/
public Iterable<T> findAll(Iterable<ID> ids) {

Set<ID> parameters = new HashSet<ID>();
Set<ID> parameters = new HashSet<ID>(tryDetermineRealSizeOrReturn(ids, 10));
for (ID id : ids) {
parameters.add(id);
}
Expand Down Expand Up @@ -234,4 +236,57 @@ protected MongoEntityInformation<T, ID> getEntityInformation() {
return entityInformation;
}

/* (non-Javadoc)
* @see org.springframework.data.mongodb.repository.MongoRepository#insert(java.lang.Object)
*/
@Override
public <S extends T> S insert(S entity) {

Assert.notNull(entity, "Entity must not be null!");

mongoOperations.insert(entity, entityInformation.getCollectionName());
return entity;
}

/* (non-Javadoc)
* @see org.springframework.data.mongodb.repository.MongoRepository#insert(java.lang.Iterable)
*/
@Override
public <S extends T> List<S> insert(Iterable<S> entities) {

Assert.notNull(entities, "The given Iterable of entities not be null!");

List<S> list = convertIterableToList(entities);

if (list.isEmpty()) {
return list;
}

mongoOperations.insertAll(list);
return list;
}

private <S extends T> List<S> convertIterableToList(Iterable<S> entities) {

if (entities instanceof List) {
return (List<S>) entities;
}

int capacity = tryDetermineRealSizeOrReturn(entities, 10);

if (capacity == 0 || entities == null) {
return Collections.<S> emptyList();
}

List<S> list = new ArrayList<S>(capacity);
for (S entity : entities) {
list.add(entity);
}

return list;
}

private int tryDetermineRealSizeOrReturn(Iterable<?> iterable, int defaultSize) {
return iterable == null ? 0 : (iterable instanceof Collection) ? ((Collection<?>) iterable).size() : defaultSize;
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2010-2012 the original author or authors.
* Copyright 2010-2014 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand All @@ -16,10 +16,16 @@
package org.springframework.data.mongodb.repository.support;

import static org.hamcrest.Matchers.*;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.*;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.UUID;

import org.junit.Before;
import org.junit.Test;
Expand All @@ -34,13 +40,13 @@

/**
* @author <a href="mailto:kowsercse@gmail.com">A. B. M. Kowser</a>
* @author Thomas Darimont
*/
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:infrastructure.xml")
public class SimpleMongoRepositoryTests {

@Autowired
private MongoTemplate template;
@Autowired private MongoTemplate template;

private Person oliver, dave, carter, boyd, stefan, leroi, alicia;
private List<Person> all;
Expand Down Expand Up @@ -69,7 +75,7 @@ public void findALlFromCustomCollectionName() {
List<Person> result = repository.findAll();
assertThat(result, hasSize(all.size()));
}

@Test
public void findOneFromCustomCollectionName() {
Person result = repository.findOne(dave.getId());
Expand All @@ -94,6 +100,76 @@ public void deleteByIdFromCustomCollectionName() {
assertThat(result, not(hasItem(dave)));
}

/**
* @see DATAMONGO-1054
*/
@Test
public void shouldInsertSingle() {

String randomId = UUID.randomUUID().toString();

Person person1 = new Person("First1" + randomId, "Last2" + randomId, 42);
person1 = repository.insert(person1);

Person saved = repository.findOne(person1.getId());

assertThat(saved, is(equalTo(person1)));
}

/**
* @see DATAMONGO-1054
*/
@Test
public void shouldInsertMutlipleFromList() {

String randomId = UUID.randomUUID().toString();

Map<String, Person> idToPerson = new HashMap<String, Person>();
List<Person> persons = new ArrayList<Person>();
for (int i = 0; i < 10; i++) {
Person person = new Person("First" + i + randomId, "Last" + randomId + i, 42 + i);
idToPerson.put(person.getId(), person);
persons.add(person);
}

List<Person> saved = repository.insert(persons);

assertThat(saved, hasSize(persons.size()));

assertThatAllReferencePersonsWereStoredCorrectly(idToPerson, saved);
}

/**
* @see DATAMONGO-1054
*/
@Test
public void shouldInsertMutlipleFromSet() {

String randomId = UUID.randomUUID().toString();

Map<String, Person> idToPerson = new HashMap<String, Person>();
Set<Person> persons = new HashSet<Person>();
for (int i = 0; i < 10; i++) {
Person person = new Person("First" + i + randomId, "Last" + i + randomId, 42 + i);
idToPerson.put(person.getId(), person);
persons.add(person);
}

List<Person> saved = repository.insert(persons);

assertThat(saved, hasSize(persons.size()));

assertThatAllReferencePersonsWereStoredCorrectly(idToPerson, saved);
}

private void assertThatAllReferencePersonsWereStoredCorrectly(Map<String, Person> references, List<Person> saved) {

for (Person person : saved) {
Person reference = references.get(person.getId());
assertThat(person, is(equalTo(reference)));
}
}

private static class CustomizedPersonInformation implements MongoEntityInformation<Person, String> {

@Override
Expand Down