DATAMONGO-1054 - Polishing.
Tweaked JavaDoc of the APIs to be less specific about implementation internals and rather point to the save(…) methods. Changed SimpleMongoRepository.save(…) methods to inspect the given entity/entities and use the optimized insert(All)-calls if all entities are considered new. Original pull request: #253.
This commit is contained in:
@@ -51,28 +51,24 @@ public interface MongoRepository<T, ID extends Serializable> extends PagingAndSo
|
|||||||
List<T> findAll(Sort 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
|
* Inserts the given a given entity. Assumes the instance to be new to be able to apply insertion optimizations. Use
|
||||||
* entity instance completely.
|
* the returned instance for further operations as the save operation might have changed the entity instance
|
||||||
* <p>
|
* completely. Prefer using {@link #save(Object)} instead to avoid the usage of store-specific API.
|
||||||
* 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
|
* @param entity must not be {@literal null}.
|
||||||
* @return the saved entity
|
* @return the saved entity
|
||||||
|
* @since 1.7
|
||||||
*/
|
*/
|
||||||
<S extends T> S insert(S entity);
|
<S extends T> S insert(S entity);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Saves all given entities.
|
* Inserts the given entities. Assumes the given entities to have not been persisted yet and thus will optimize the
|
||||||
* <p>
|
* insert over a call to {@link #save(Iterable)}. Prefer using {@link #save(Iterable)} to avoid the usage of store
|
||||||
* This uses {@link org.springframework.data.mongodb.core.MongoTemplate#insert(Object)} for storing the given entity.
|
* specific API.
|
||||||
* <p>
|
|
||||||
* Note that this method does neither fire any save events nor nor performs any id population or version checking.
|
|
||||||
*
|
*
|
||||||
* @param entities
|
* @param entities must not be {@literal null}.
|
||||||
* @return the saved entities
|
* @return the saved entities
|
||||||
* @throws IllegalArgumentException in case the given entity is (@literal null}.
|
* @since 1.7
|
||||||
*/
|
*/
|
||||||
<S extends T> List<S> insert(Iterable<S> entities);
|
<S extends T> List<S> insert(Iterable<S> entities);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -29,6 +29,7 @@ import org.springframework.data.mongodb.repository.query.MongoEntityInformation;
|
|||||||
import org.springframework.data.querydsl.EntityPathResolver;
|
import org.springframework.data.querydsl.EntityPathResolver;
|
||||||
import org.springframework.data.querydsl.QueryDslPredicateExecutor;
|
import org.springframework.data.querydsl.QueryDslPredicateExecutor;
|
||||||
import org.springframework.data.querydsl.SimpleEntityPathResolver;
|
import org.springframework.data.querydsl.SimpleEntityPathResolver;
|
||||||
|
import org.springframework.data.repository.core.EntityInformation;
|
||||||
import org.springframework.data.repository.core.EntityMetadata;
|
import org.springframework.data.repository.core.EntityMetadata;
|
||||||
import org.springframework.util.Assert;
|
import org.springframework.util.Assert;
|
||||||
|
|
||||||
@@ -48,13 +49,15 @@ public class QueryDslMongoRepository<T, ID extends Serializable> extends SimpleM
|
|||||||
QueryDslPredicateExecutor<T> {
|
QueryDslPredicateExecutor<T> {
|
||||||
|
|
||||||
private final PathBuilder<T> builder;
|
private final PathBuilder<T> builder;
|
||||||
|
private final EntityInformation<T, ID> entityInformation;
|
||||||
|
private final MongoOperations mongoOperations;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a new {@link QueryDslMongoRepository} for the given {@link EntityMetadata} and {@link MongoTemplate}. Uses
|
* Creates a new {@link QueryDslMongoRepository} for the given {@link EntityMetadata} and {@link MongoTemplate}. Uses
|
||||||
* the {@link SimpleEntityPathResolver} to create an {@link EntityPath} for the given domain class.
|
* the {@link SimpleEntityPathResolver} to create an {@link EntityPath} for the given domain class.
|
||||||
*
|
*
|
||||||
* @param entityInformation
|
* @param entityInformation must not be {@literal null}.
|
||||||
* @param template
|
* @param mongoOperations must not be {@literal null}.
|
||||||
*/
|
*/
|
||||||
public QueryDslMongoRepository(MongoEntityInformation<T, ID> entityInformation, MongoOperations mongoOperations) {
|
public QueryDslMongoRepository(MongoEntityInformation<T, ID> entityInformation, MongoOperations mongoOperations) {
|
||||||
this(entityInformation, mongoOperations, SimpleEntityPathResolver.INSTANCE);
|
this(entityInformation, mongoOperations, SimpleEntityPathResolver.INSTANCE);
|
||||||
@@ -64,17 +67,21 @@ public class QueryDslMongoRepository<T, ID extends Serializable> extends SimpleM
|
|||||||
* Creates a new {@link QueryDslMongoRepository} for the given {@link MongoEntityInformation}, {@link MongoTemplate}
|
* Creates a new {@link QueryDslMongoRepository} for the given {@link MongoEntityInformation}, {@link MongoTemplate}
|
||||||
* and {@link EntityPathResolver}.
|
* and {@link EntityPathResolver}.
|
||||||
*
|
*
|
||||||
* @param entityInformation
|
* @param entityInformation must not be {@literal null}.
|
||||||
* @param mongoOperations
|
* @param mongoOperations must not be {@literal null}.
|
||||||
* @param resolver
|
* @param resolver must not be {@literal null}.
|
||||||
*/
|
*/
|
||||||
public QueryDslMongoRepository(MongoEntityInformation<T, ID> entityInformation, MongoOperations mongoOperations,
|
public QueryDslMongoRepository(MongoEntityInformation<T, ID> entityInformation, MongoOperations mongoOperations,
|
||||||
EntityPathResolver resolver) {
|
EntityPathResolver resolver) {
|
||||||
|
|
||||||
super(entityInformation, mongoOperations);
|
super(entityInformation, mongoOperations);
|
||||||
|
|
||||||
Assert.notNull(resolver);
|
Assert.notNull(resolver);
|
||||||
EntityPath<T> path = resolver.createPath(entityInformation.getJavaType());
|
EntityPath<T> path = resolver.createPath(entityInformation.getJavaType());
|
||||||
|
|
||||||
this.builder = new PathBuilder<T>(path.getType(), path.getMetadata());
|
this.builder = new PathBuilder<T>(path.getType(), path.getMetadata());
|
||||||
|
this.entityInformation = entityInformation;
|
||||||
|
this.mongoOperations = mongoOperations;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -139,9 +146,9 @@ public class QueryDslMongoRepository<T, ID extends Serializable> extends SimpleM
|
|||||||
*/
|
*/
|
||||||
private MongodbQuery<T> createQueryFor(Predicate... predicate) {
|
private MongodbQuery<T> createQueryFor(Predicate... predicate) {
|
||||||
|
|
||||||
Class<T> domainType = getEntityInformation().getJavaType();
|
Class<T> domainType = entityInformation.getJavaType();
|
||||||
|
|
||||||
MongodbQuery<T> query = new SpringDataMongodbQuery<T>(getMongoOperations(), domainType);
|
MongodbQuery<T> query = new SpringDataMongodbQuery<T>(mongoOperations, domainType);
|
||||||
return query.where(predicate);
|
return query.where(predicate);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -72,7 +72,12 @@ public class SimpleMongoRepository<T, ID extends Serializable> implements MongoR
|
|||||||
|
|
||||||
Assert.notNull(entity, "Entity must not be null!");
|
Assert.notNull(entity, "Entity must not be null!");
|
||||||
|
|
||||||
mongoOperations.save(entity, entityInformation.getCollectionName());
|
if (entityInformation.isNew(entity)) {
|
||||||
|
mongoOperations.insert(entity, entityInformation.getCollectionName());
|
||||||
|
} else {
|
||||||
|
mongoOperations.save(entity, entityInformation.getCollectionName());
|
||||||
|
}
|
||||||
|
|
||||||
return entity;
|
return entity;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -84,11 +89,22 @@ public class SimpleMongoRepository<T, ID extends Serializable> implements MongoR
|
|||||||
|
|
||||||
Assert.notNull(entities, "The given Iterable of entities not be null!");
|
Assert.notNull(entities, "The given Iterable of entities not be null!");
|
||||||
|
|
||||||
List<S> result = new ArrayList<S>(tryDetermineRealSizeOrReturn(entities, 10));
|
List<S> result = convertIterableToList(entities);
|
||||||
|
boolean allNew = true;
|
||||||
|
|
||||||
for (S entity : entities) {
|
for (S entity : entities) {
|
||||||
save(entity);
|
if (allNew && !entityInformation.isNew(entity)) {
|
||||||
result.add(entity);
|
allNew = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (allNew) {
|
||||||
|
mongoOperations.insertAll(result);
|
||||||
|
} else {
|
||||||
|
|
||||||
|
for (S entity : result) {
|
||||||
|
save(entity);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
@@ -211,32 +227,8 @@ public class SimpleMongoRepository<T, ID extends Serializable> implements MongoR
|
|||||||
return findAll(new Query().with(sort));
|
return findAll(new Query().with(sort));
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<T> findAll(Query query) {
|
/*
|
||||||
|
* (non-Javadoc)
|
||||||
if (query == null) {
|
|
||||||
return Collections.emptyList();
|
|
||||||
}
|
|
||||||
|
|
||||||
return mongoOperations.find(query, entityInformation.getJavaType(), entityInformation.getCollectionName());
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the underlying {@link MongoOperations} instance.
|
|
||||||
*
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
protected MongoOperations getMongoOperations() {
|
|
||||||
return this.mongoOperations;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return the entityInformation
|
|
||||||
*/
|
|
||||||
protected MongoEntityInformation<T, ID> getEntityInformation() {
|
|
||||||
return entityInformation;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* (non-Javadoc)
|
|
||||||
* @see org.springframework.data.mongodb.repository.MongoRepository#insert(java.lang.Object)
|
* @see org.springframework.data.mongodb.repository.MongoRepository#insert(java.lang.Object)
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
@@ -248,7 +240,8 @@ public class SimpleMongoRepository<T, ID extends Serializable> implements MongoR
|
|||||||
return entity;
|
return entity;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* (non-Javadoc)
|
/*
|
||||||
|
* (non-Javadoc)
|
||||||
* @see org.springframework.data.mongodb.repository.MongoRepository#insert(java.lang.Iterable)
|
* @see org.springframework.data.mongodb.repository.MongoRepository#insert(java.lang.Iterable)
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
@@ -266,27 +259,36 @@ public class SimpleMongoRepository<T, ID extends Serializable> implements MongoR
|
|||||||
return list;
|
return list;
|
||||||
}
|
}
|
||||||
|
|
||||||
private <S extends T> List<S> convertIterableToList(Iterable<S> entities) {
|
private List<T> findAll(Query query) {
|
||||||
|
|
||||||
|
if (query == null) {
|
||||||
|
return Collections.emptyList();
|
||||||
|
}
|
||||||
|
|
||||||
|
return mongoOperations.find(query, entityInformation.getJavaType(), entityInformation.getCollectionName());
|
||||||
|
}
|
||||||
|
|
||||||
|
private static <T> List<T> convertIterableToList(Iterable<T> entities) {
|
||||||
|
|
||||||
if (entities instanceof List) {
|
if (entities instanceof List) {
|
||||||
return (List<S>) entities;
|
return (List<T>) entities;
|
||||||
}
|
}
|
||||||
|
|
||||||
int capacity = tryDetermineRealSizeOrReturn(entities, 10);
|
int capacity = tryDetermineRealSizeOrReturn(entities, 10);
|
||||||
|
|
||||||
if (capacity == 0 || entities == null) {
|
if (capacity == 0 || entities == null) {
|
||||||
return Collections.<S> emptyList();
|
return Collections.<T> emptyList();
|
||||||
}
|
}
|
||||||
|
|
||||||
List<S> list = new ArrayList<S>(capacity);
|
List<T> list = new ArrayList<T>(capacity);
|
||||||
for (S entity : entities) {
|
for (T entity : entities) {
|
||||||
list.add(entity);
|
list.add(entity);
|
||||||
}
|
}
|
||||||
|
|
||||||
return list;
|
return list;
|
||||||
}
|
}
|
||||||
|
|
||||||
private int tryDetermineRealSizeOrReturn(Iterable<?> iterable, int defaultSize) {
|
private static int tryDetermineRealSizeOrReturn(Iterable<?> iterable, int defaultSize) {
|
||||||
return iterable == null ? 0 : (iterable instanceof Collection) ? ((Collection<?>) iterable).size() : defaultSize;
|
return iterable == null ? 0 : (iterable instanceof Collection) ? ((Collection<?>) iterable).size() : defaultSize;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -123,9 +123,9 @@ public class SimpleMongoRepositoryTests {
|
|||||||
public void shouldInsertMutlipleFromList() {
|
public void shouldInsertMutlipleFromList() {
|
||||||
|
|
||||||
String randomId = UUID.randomUUID().toString();
|
String randomId = UUID.randomUUID().toString();
|
||||||
|
|
||||||
Map<String, Person> idToPerson = new HashMap<String, Person>();
|
Map<String, Person> idToPerson = new HashMap<String, Person>();
|
||||||
List<Person> persons = new ArrayList<Person>();
|
List<Person> persons = new ArrayList<Person>();
|
||||||
|
|
||||||
for (int i = 0; i < 10; i++) {
|
for (int i = 0; i < 10; i++) {
|
||||||
Person person = new Person("First" + i + randomId, "Last" + randomId + i, 42 + i);
|
Person person = new Person("First" + i + randomId, "Last" + randomId + i, 42 + i);
|
||||||
idToPerson.put(person.getId(), person);
|
idToPerson.put(person.getId(), person);
|
||||||
@@ -135,7 +135,6 @@ public class SimpleMongoRepositoryTests {
|
|||||||
List<Person> saved = repository.insert(persons);
|
List<Person> saved = repository.insert(persons);
|
||||||
|
|
||||||
assertThat(saved, hasSize(persons.size()));
|
assertThat(saved, hasSize(persons.size()));
|
||||||
|
|
||||||
assertThatAllReferencePersonsWereStoredCorrectly(idToPerson, saved);
|
assertThatAllReferencePersonsWereStoredCorrectly(idToPerson, saved);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -146,9 +145,9 @@ public class SimpleMongoRepositoryTests {
|
|||||||
public void shouldInsertMutlipleFromSet() {
|
public void shouldInsertMutlipleFromSet() {
|
||||||
|
|
||||||
String randomId = UUID.randomUUID().toString();
|
String randomId = UUID.randomUUID().toString();
|
||||||
|
|
||||||
Map<String, Person> idToPerson = new HashMap<String, Person>();
|
Map<String, Person> idToPerson = new HashMap<String, Person>();
|
||||||
Set<Person> persons = new HashSet<Person>();
|
Set<Person> persons = new HashSet<Person>();
|
||||||
|
|
||||||
for (int i = 0; i < 10; i++) {
|
for (int i = 0; i < 10; i++) {
|
||||||
Person person = new Person("First" + i + randomId, "Last" + i + randomId, 42 + i);
|
Person person = new Person("First" + i + randomId, "Last" + i + randomId, 42 + i);
|
||||||
idToPerson.put(person.getId(), person);
|
idToPerson.put(person.getId(), person);
|
||||||
@@ -158,7 +157,6 @@ public class SimpleMongoRepositoryTests {
|
|||||||
List<Person> saved = repository.insert(persons);
|
List<Person> saved = repository.insert(persons);
|
||||||
|
|
||||||
assertThat(saved, hasSize(persons.size()));
|
assertThat(saved, hasSize(persons.size()));
|
||||||
|
|
||||||
assertThatAllReferencePersonsWereStoredCorrectly(idToPerson, saved);
|
assertThatAllReferencePersonsWereStoredCorrectly(idToPerson, saved);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user