Skip to content

DATAMONGO-1188 - Add suport for findAndModify in query derivation. #284

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-1188-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-1188-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-1188-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-1188-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-1188-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-1188-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
import org.springframework.data.mongodb.core.MongoOperations;
import org.springframework.data.mongodb.core.query.NearQuery;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;
import org.springframework.data.repository.query.ParameterAccessor;
import org.springframework.data.repository.query.RepositoryQuery;
import org.springframework.data.util.CloseableIterator;
Expand Down Expand Up @@ -101,10 +102,20 @@ public Object execute(Object[] parameters) {
} else if (method.isSliceQuery()) {
return new SlicedExecution(accessor.getPageable()).execute(query);
} else if (method.isCollectionQuery()) {

if (method.isModifyingQuery()) {
return new UpdatingCollectionExecution(accessor.getPageable(), accessor.getUpdate()).execute(query);
}

return new CollectionExecution(accessor.getPageable()).execute(query);
} else if (method.isPageQuery()) {
return new PagedExecution(accessor.getPageable()).execute(query);
} else {

if (method.isModifyingQuery()) {
return new UpdatingSingleEntityExecution(accessor.getUpdate()).execute(query);
}

return new SingleEntityExecution(isCountQuery()).execute(query);
}
}
Expand Down Expand Up @@ -194,6 +205,30 @@ public Object execute(Query query) {
}
}

/**
* {@link Execution} for collection returning find and update queries.
*
* @author Thomas Darimont
*/
final class UpdatingCollectionExecution extends Execution {

private final Pageable pageable;
private final Update update;

UpdatingCollectionExecution(Pageable pageable, Update update) {
this.pageable = pageable;
this.update = update;
}

@Override
Object execute(Query query) {

MongoEntityMetadata<?> metadata = method.getEntityInformation();
return operations.findAndModify(query.with(pageable), update, metadata.getJavaType(),
metadata.getCollectionName());
}
}

/**
* {@link Execution} for {@link Slice} query methods.
*
Expand Down Expand Up @@ -313,6 +348,31 @@ Object execute(Query query) {
}
}

/**
* {@link Execution} to return a single entity with update.
*
* @author Thomas Darimont
*/
final class UpdatingSingleEntityExecution extends Execution {

private final Update update;

private UpdatingSingleEntityExecution(Update update) {
this.update = update;
}

/*
* (non-Javadoc)
* @see org.springframework.data.mongodb.repository.AbstractMongoQuery.Execution#execute(org.springframework.data.mongodb.core.core.query.Query)
*/
@Override
Object execute(Query query) {

MongoEntityMetadata<?> metadata = method.getEntityInformation();
return operations.findAndModify(query.limit(1), update, metadata.getJavaType(), metadata.getCollectionName());
}
}

/**
* {@link Execution} to execute geo-near queries.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
import org.springframework.data.mongodb.core.convert.MongoWriter;
import org.springframework.data.mongodb.core.mapping.MongoPersistentProperty;
import org.springframework.data.mongodb.core.query.TextCriteria;
import org.springframework.data.mongodb.core.query.Update;
import org.springframework.data.repository.query.ParameterAccessor;
import org.springframework.data.util.TypeInformation;
import org.springframework.util.Assert;
Expand Down Expand Up @@ -255,4 +256,11 @@ public interface PotentiallyConvertingIterator extends Iterator<Object> {
Object nextConverted(MongoPersistentProperty property);
}

/* (non-Javadoc)
* @see org.springframework.data.mongodb.repository.query.MongoParameterAccessor#getUpdate()
*/
@Override
public Update getUpdate() {
return delegate.getUpdate();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,15 @@
import org.springframework.data.geo.Distance;
import org.springframework.data.geo.Point;
import org.springframework.data.mongodb.core.query.TextCriteria;
import org.springframework.data.mongodb.core.query.Update;
import org.springframework.data.repository.query.ParameterAccessor;

/**
* Mongo-specific {@link ParameterAccessor} exposing a maximum distance parameter.
*
* @author Oliver Gierke
* @author Christoph Strobl
* @author Thomas Darimont
*/
public interface MongoParameterAccessor extends ParameterAccessor {

Expand All @@ -51,4 +53,12 @@ public interface MongoParameterAccessor extends ParameterAccessor {
* @since 1.6
*/
TextCriteria getFullText();

/**
* Returns the {@link Update} to be used for findAndUpdate query.
*
* @return
* @since 1.7
*/
Update getUpdate();
}
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
import org.springframework.data.geo.Distance;
import org.springframework.data.geo.Point;
import org.springframework.data.mongodb.core.query.TextCriteria;
import org.springframework.data.mongodb.core.query.Update;
import org.springframework.data.mongodb.repository.Near;
import org.springframework.data.mongodb.repository.query.MongoParameters.MongoParameter;
import org.springframework.data.repository.query.Parameter;
Expand All @@ -36,12 +37,14 @@
*
* @author Oliver Gierke
* @author Christoph Strobl
* @author Thomas Darimont
*/
public class MongoParameters extends Parameters<MongoParameters, MongoParameter> {

private final int rangeIndex;
private final int maxDistanceIndex;
private final Integer fullTextIndex;
private final int updateIndex;

private Integer nearIndex;

Expand All @@ -63,6 +66,7 @@ public MongoParameters(Method method, boolean isGeoNearMethod) {

this.rangeIndex = getTypeIndex(parameterTypeInfo, Range.class, Distance.class);
this.maxDistanceIndex = this.rangeIndex == -1 ? getTypeIndex(parameterTypeInfo, Distance.class, null) : -1;
this.updateIndex = parameterTypes.indexOf(Update.class);

if (this.nearIndex == null && isGeoNearMethod) {
this.nearIndex = getNearIndex(parameterTypes);
Expand All @@ -72,14 +76,15 @@ public MongoParameters(Method method, boolean isGeoNearMethod) {
}

private MongoParameters(List<MongoParameter> parameters, int maxDistanceIndex, Integer nearIndex,
Integer fullTextIndex, int rangeIndex) {
Integer fullTextIndex, int rangeIndex, int updateIndex) {

super(parameters);

this.nearIndex = nearIndex;
this.fullTextIndex = fullTextIndex;
this.maxDistanceIndex = maxDistanceIndex;
this.rangeIndex = rangeIndex;
this.updateIndex = updateIndex;
}

private final int getNearIndex(List<Class<?>> parameterTypes) {
Expand Down Expand Up @@ -188,7 +193,8 @@ public int getRangeIndex() {
*/
@Override
protected MongoParameters createFrom(List<MongoParameter> parameters) {
return new MongoParameters(parameters, this.maxDistanceIndex, this.nearIndex, this.fullTextIndex, this.rangeIndex);
return new MongoParameters(parameters, this.maxDistanceIndex, this.nearIndex, this.fullTextIndex, this.rangeIndex,
this.updateIndex);
}

private int getTypeIndex(List<TypeInformation<?>> parameterTypes, Class<?> type, Class<?> componentType) {
Expand Down Expand Up @@ -259,7 +265,9 @@ private boolean isPoint() {
private boolean hasNearAnnotation() {
return parameter.getParameterAnnotation(Near.class) != null;
}

}

public int getUpdateIndex() {
return updateIndex;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
import org.springframework.data.geo.Point;
import org.springframework.data.mongodb.core.query.Term;
import org.springframework.data.mongodb.core.query.TextCriteria;
import org.springframework.data.mongodb.core.query.Update;
import org.springframework.data.repository.query.ParametersParameterAccessor;
import org.springframework.util.Assert;
import org.springframework.util.ClassUtils;
Expand All @@ -29,6 +30,7 @@
*
* @author Oliver Gierke
* @author Christoph Strobl
* @author Thomas Darimont
*/
public class MongoParametersParameterAccessor extends ParametersParameterAccessor implements MongoParameterAccessor {

Expand Down Expand Up @@ -121,4 +123,11 @@ protected TextCriteria potentiallyConvertFullText(Object fullText) {
"Expected full text parameter to be one of String, Term or TextCriteria but found %s.",
ClassUtils.getShortName(fullText.getClass())));
}

@Override
public Update getUpdate() {

int updateIndex = method.getParameters().getUpdateIndex();
return updateIndex == -1 ? null : (Update) getValue(updateIndex);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
import org.springframework.data.mapping.context.MappingContext;
import org.springframework.data.mongodb.core.mapping.MongoPersistentEntity;
import org.springframework.data.mongodb.core.mapping.MongoPersistentProperty;
import org.springframework.data.mongodb.core.query.Update;
import org.springframework.data.mongodb.repository.Meta;
import org.springframework.data.mongodb.repository.Query;
import org.springframework.data.repository.core.RepositoryMetadata;
Expand Down Expand Up @@ -233,4 +234,11 @@ public org.springframework.data.mongodb.core.query.Meta getQueryMetaAttributes()

return metaAttributes;
}

@Override
public boolean isModifyingQuery() {

Class<?>[] parameterTypes = this.method.getParameterTypes();
return parameterTypes.length > 0 && parameterTypes[parameterTypes.length - 1] == Update.class;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@
import org.springframework.data.geo.Polygon;
import org.springframework.data.mongodb.core.MongoOperations;
import org.springframework.data.mongodb.core.query.BasicQuery;
import org.springframework.data.mongodb.core.query.Update;
import org.springframework.data.mongodb.repository.Person.Sex;
import org.springframework.data.querydsl.QSort;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
Expand Down Expand Up @@ -1183,4 +1184,36 @@ public void executesGeoNearQueryForResultsCorrectlyWhenGivenMinAndMaxDistance()
GeoResults<Person> results = repository.findPersonByLocationNear(new Point(-73.99, 40.73), range);
assertThat(results.getContent().isEmpty(), is(false));
}

/**
* @see DATAMONGO-1188
*/
@Test
public void shouldSupportFindAndModfiyForQueryDerivationWithCollectionResult() {

List<Person> result = repository.findAndModifyByFirstname("Dave", new Update().inc("visits", 42));

assertThat(result.size(), is(1));
assertThat(result.get(0), is(dave));

Person dave = repository.findOne(result.get(0).getId());

assertThat(dave.visits, is(42));
}

/**
* @see DATAMONGO-1188
*/
@Test
public void shouldSupportFindAndModfiyForQueryDerivationWithSingleResult() {

Person result = repository.findOneAndModifyByFirstname("Dave", new Update().inc("visits", 1337));

assertThat(result, is(dave));

Person dave = repository.findOne(result.getId());

assertThat(dave.visits, is(1337));
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,8 @@ public enum Sex {

Credentials credentials;

int visits;

public Person() {

this(null, null);
Expand Down Expand Up @@ -245,6 +247,14 @@ public void setCoworker(User coworker) {
this.coworker = coworker;
}

public int getVisits() {
return visits;
}

public void setVisits(int visits) {
this.visits = visits;
}

/*
* (non-Javadoc)
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
import org.springframework.data.geo.GeoResults;
import org.springframework.data.geo.Point;
import org.springframework.data.geo.Polygon;
import org.springframework.data.mongodb.core.query.Update;
import org.springframework.data.mongodb.repository.Person.Sex;
import org.springframework.data.querydsl.QueryDslPredicateExecutor;

Expand Down Expand Up @@ -333,4 +334,8 @@ public interface PersonRepository extends MongoRepository<Person, String>, Query
*/
@Query("{ firstname : { $in : ?0 }}")
Stream<Person> findByCustomQueryWithStreamingCursorByFirstnames(List<String> firstnames);

List<Person> findAndModifyByFirstname(String firstname, Update update);

Person findOneAndModifyByFirstname(String firstname, Update update);
}
Loading