DATAMONGO-1054 - Add support for fast insertion via MongoRepository.insert(..).
Introduced new insert(..) method variants on MongoRepositories that delegates to MongoTemplate.insert(..). This bypasses ID-population, save event generation and version checking and allows for fast insertion of bulk data. Original pull request: #253.
This commit is contained in:
committed by
Oliver Gierke
parent
08faa52ef4
commit
a212b7566c
@@ -27,6 +27,7 @@ import org.springframework.data.repository.PagingAndSortingRepository;
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
* @author Christoph Strobl
|
||||
* @author Thomas Darimont
|
||||
*/
|
||||
@NoRepositoryBean
|
||||
public interface MongoRepository<T, ID extends Serializable> extends PagingAndSortingRepository<T, ID> {
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -19,6 +19,7 @@ import static org.springframework.data.mongodb.core.query.Criteria.*;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
@@ -41,6 +42,7 @@ import org.springframework.util.Assert;
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
* @author Christoph Strobl
|
||||
* @author Thomas Darimont
|
||||
*/
|
||||
public class SimpleMongoRepository<T, ID extends Serializable> implements MongoRepository<T, ID> {
|
||||
|
||||
@@ -48,7 +50,7 @@ public class SimpleMongoRepository<T, ID extends Serializable> implements MongoR
|
||||
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}.
|
||||
@@ -82,7 +84,7 @@ public class SimpleMongoRepository<T, ID extends Serializable> implements MongoR
|
||||
|
||||
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);
|
||||
@@ -181,7 +183,7 @@ public class SimpleMongoRepository<T, ID extends Serializable> implements MongoR
|
||||
*/
|
||||
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);
|
||||
}
|
||||
@@ -234,4 +236,57 @@ public class SimpleMongoRepository<T, ID extends Serializable> implements MongoR
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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.
|
||||
@@ -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;
|
||||
@@ -34,13 +40,13 @@ import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
|
||||
/**
|
||||
* @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;
|
||||
@@ -69,7 +75,7 @@ public class SimpleMongoRepositoryTests {
|
||||
List<Person> result = repository.findAll();
|
||||
assertThat(result, hasSize(all.size()));
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void findOneFromCustomCollectionName() {
|
||||
Person result = repository.findOne(dave.getId());
|
||||
@@ -94,6 +100,76 @@ public class SimpleMongoRepositoryTests {
|
||||
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
|
||||
|
||||
Reference in New Issue
Block a user