Compare commits

..

19 Commits

Author SHA1 Message Date
Oliver Gierke
4ca16f8d15 DATAMONGO-456 - Fixed <db-factory /> element documentation in XSD. 2012-09-17 12:20:52 +02:00
Oliver Gierke
1b3d49e466 DATAMONGO-457 - Fixed links in reference documentation. 2012-09-17 12:09:05 +02:00
Oliver Gierke
bf89cce43c DATAMONGO-539 - Fixed MongoTemplate.remove(object, collectionName).
If the entity being removed using MongoTemplate.remove(object, collectionName) contained an id that could be converted into an ObjectID it wasn't removed correctly currently. This was caused by the fact that the intermediate call didn't hand over the entity type and thus the id conversion failed. This in turn caused the query not to match the previous saved object.
2012-09-17 11:44:30 +02:00
Oliver Gierke
aef493fdb8 DATAMONGO-539 - Added test case to show removing entity from explicit collection works. 2012-09-13 17:24:27 +02:00
Oliver Gierke
eabd47ae8d DATAMONGO-532 - Synchronize DB authentication.
In multithreaded environments Mongo database authentication can be triggered twice if two or more threads refer to the same db instance. This is now prevented by synchronizing calls to db.authenticate(…).
2012-09-12 13:00:46 +02:00
Oliver Gierke
1d9ee9a28f DATAMONGO-537 - Work around compiler issues with generics. 2012-09-12 10:40:19 +02:00
Oliver Gierke
e0b0792643 DATAMONGO-537 - Guard index creation tests against changing method orders. 2012-09-12 10:11:26 +02:00
Oliver Gierke
d5f8285d51 DATAMONGO-529 - Update Querydsl setup to use 1.0.4.
Raised Maven compiler plugin version to 2.5.1.
2012-09-11 18:17:20 +02:00
Oliver Gierke
4ce8da7ebf DATAMONGO-536 - Fixed package cycle introduced by SerializationUtils. 2012-09-11 18:08:56 +02:00
Oliver Gierke
c1030abe96 DATAMONGO-512 - Fixed broken handling of AND in query methods.
Apparently the fix fof DATAMONGO-469 was messed up later on.
2012-09-04 07:32:27 +02:00
Oliver Gierke
2a8f13d5d5 DATAMONGO-527 - Fixed Criteria.equals(…). 2012-09-04 07:32:27 +02:00
Spring Buildmaster
e4adc0ce23 DATAMONGO-514 - Prepare next development iteration. 2012-08-24 01:54:30 -07:00
Spring Buildmaster
beeed68873 DATAMONGO-514 - Release 1.0.4.RELEASE. 2012-08-24 01:54:26 -07:00
Oliver Gierke
22872f97dc DATAMONGO-514 - Prepare changelog for 1.0.4.RELEASE. 2012-08-24 10:43:54 +02:00
Oliver Gierke
323de58efc DATAMONGO-499 - Fixed namespace reference to repository XSD. 2012-07-31 11:00:23 +02:00
Oliver Gierke
58f12b8d8f DATAMONGO-494 - QueryMapper now forwards entity metadata into nested $(n)or criterias.
Introduced helper class to ease assertions on DBObjects as well.
2012-07-27 16:16:57 +02:00
Oliver Gierke
48cb155f6c DATAMONGO-493 - Fixed broken $ne handling in QueryMapper.
$ne expressions are now only being tried to be converted into an ObjectId in case they follow an id property. Previously they tried in every case which might have led to Strings being converted into ObjectIds that accidentally were valid ObjectIds but didn't represent an id at all.
2012-07-27 16:16:29 +02:00
Oliver Gierke
594ddbd1c1 DATAMONGO-495 - Fixed debug output in MongoTemplate.doFind(…).
Using SerializationUtils to safely output the query to be executed.
2012-07-26 10:29:11 +02:00
Spring Buildmaster
2c2bbf415b DATAMONGO-492 - Prepare next development iteration. 2012-07-24 07:01:24 -07:00
25 changed files with 305 additions and 84 deletions

View File

@@ -6,7 +6,7 @@
<name>Spring Data MongoDB Distribution</name>
<description>Spring Data project for MongoDB</description>
<url>http://www.springsource.org/spring-data/mongodb</url>
<version>1.0.3.RELEASE</version>
<version>1.0.5.BUILD-SNAPSHOT</version>
<packaging>pom</packaging>
<modules>
<module>spring-data-mongodb</module>

View File

@@ -4,7 +4,7 @@
<parent>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-mongodb-parent</artifactId>
<version>1.0.3.RELEASE</version>
<version>1.0.5.BUILD-SNAPSHOT</version>
<relativePath>../spring-data-mongodb-parent/pom.xml</relativePath>
</parent>
<artifactId>spring-data-mongodb-cross-store</artifactId>

View File

@@ -4,7 +4,7 @@
<parent>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-mongodb-parent</artifactId>
<version>1.0.3.RELEASE</version>
<version>1.0.5.BUILD-SNAPSHOT</version>
<relativePath>../spring-data-mongodb-parent/pom.xml</relativePath>
</parent>
<artifactId>spring-data-mongodb-log4j</artifactId>

View File

@@ -6,7 +6,7 @@
<name>Spring Data MongoDB Parent</name>
<description>Spring Data project for MongoDB</description>
<url>http://www.springsource.org/spring-data/mongodb</url>
<version>1.0.3.RELEASE</version>
<version>1.0.5.BUILD-SNAPSHOT</version>
<packaging>pom</packaging>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
@@ -198,7 +198,7 @@
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-mongodb</artifactId>
<version>1.0.3.RELEASE</version>
<version>1.0.5.BUILD-SNAPSHOT</version>
</dependency>
<!-- Logging -->
@@ -297,7 +297,7 @@
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>2.4</version>
<version>2.5.1</version>
<configuration>
<source>1.5</source>
<target>1.5</target>
@@ -378,6 +378,10 @@
<id>spring-plugins-release</id>
<url>http://repo.springsource.org/plugins-release</url>
</pluginRepository>
<pluginRepository>
<id>querydsl</id>
<url>http://source.mysema.com/maven2/releases</url>
</pluginRepository>
</pluginRepositories>
<repositories>
<repository>

View File

@@ -4,7 +4,7 @@
<parent>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-mongodb-parent</artifactId>
<version>1.0.3.RELEASE</version>
<version>1.0.5.BUILD-SNAPSHOT</version>
<relativePath>../spring-data-mongodb-parent/pom.xml</relativePath>
</parent>
<artifactId>spring-data-mongodb</artifactId>
@@ -69,19 +69,6 @@
<artifactId>querydsl-mongodb</artifactId>
<version>${querydsl.version}</version>
<optional>true</optional>
<exclusions>
<exclusion>
<groupId>com.google.code.morphia</groupId>
<artifactId>morphia</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>com.mysema.querydsl</groupId>
<artifactId>querydsl-apt</artifactId>
<version>${querydsl.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
@@ -131,7 +118,14 @@
<plugin>
<groupId>com.mysema.maven</groupId>
<artifactId>maven-apt-plugin</artifactId>
<version>1.0.2</version>
<version>1.0.4</version>
<dependencies>
<dependency>
<groupId>com.mysema.querydsl</groupId>
<artifactId>querydsl-apt</artifactId>
<version>${querydsl.version}</version>
</dependency>
</dependencies>
<executions>
<execution>
<phase>generate-test-sources</phase>

View File

@@ -97,10 +97,12 @@ public abstract class MongoDbUtils {
boolean credentialsGiven = username != null && password != null;
if (credentialsGiven && !db.isAuthenticated()) {
// Note, can only authenticate once against the same com.mongodb.DB object.
if (!db.authenticate(username, password)) {
throw new CannotGetMongoDbConnectionException("Failed to authenticate to database [" + databaseName
+ "], username = [" + username + "], password = [" + new String(password) + "]", databaseName, username,
password);
synchronized (db) {
if (!db.authenticate(username, password)) {
throw new CannotGetMongoDbConnectionException("Failed to authenticate to database [" + databaseName
+ "], username = [" + username + "], password = [" + new String(password) + "]", databaseName, username,
password);
}
}
}
@@ -144,7 +146,7 @@ public abstract class MongoDbUtils {
return false;
}
DbHolder dbHolder = (DbHolder) TransactionSynchronizationManager.getResource(mongo);
return (dbHolder != null && dbHolder.containsDB(db));
return dbHolder != null && dbHolder.containsDB(db);
}
/**

View File

@@ -1,15 +1,11 @@
/*
* Copyright 2010-2011 the original author or authors.
* Copyright 2010-2012 the original author or authors.
*
* Licensed under t
import org.springframework.util.ResourceUtils;
import org.springframework.data.convert.EntityReader;
he Apache License, Version 2.0 (the "License");
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
@@ -20,6 +16,7 @@ he Apache License, Version 2.0 (the "License");
package org.springframework.data.mongodb.core;
import static org.springframework.data.mongodb.core.query.Criteria.*;
import static org.springframework.data.mongodb.core.query.SerializationUtils.*;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
@@ -340,7 +337,7 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware {
if (LOGGER.isDebugEnabled()) {
LOGGER.debug(String.format("Executing query: %s sort: %s fields: %s in collection: $s",
SerializationUtils.serializeToJsonSafely(queryObject), sortObject, fieldsObject, collectionName));
serializeToJsonSafely(queryObject), sortObject, fieldsObject, collectionName));
}
this.executeQueryInternal(new FindCallback(queryObject, fieldsObject), preparer, dch, collectionName);
@@ -459,7 +456,7 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware {
} else {
query.limit(1);
List<T> results = find(query, entityClass, collectionName);
return (results.isEmpty() ? null : results.get(0));
return results.isEmpty() ? null : results.get(0);
}
}
@@ -882,12 +879,12 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware {
return;
}
remove(getIdQueryFor(object), collection);
doRemove(collection, getIdQueryFor(object), object.getClass());
}
/**
* Returns a {@link Query} for the given entity by its id.
*
*
* @param object must not be {@literal null}.
* @return
*/
@@ -1011,8 +1008,7 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware {
handleCommandError(commandResult, commandObject);
if (LOGGER.isDebugEnabled()) {
LOGGER.debug(String.format("MapReduce command result = [%s]",
SerializationUtils.serializeToJsonSafely(commandObject)));
LOGGER.debug(String.format("MapReduce command result = [%s]", serializeToJsonSafely(commandObject)));
}
MapReduceOutput mapReduceOutput = new MapReduceOutput(inputCollection, commandObject, commandResult);
@@ -1065,8 +1061,7 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware {
DBObject commandObject = new BasicDBObject("group", dbo);
if (LOGGER.isDebugEnabled()) {
LOGGER.debug(String.format("Executing Group with DBObject [%s]",
SerializationUtils.serializeToJsonSafely(commandObject)));
LOGGER.debug(String.format("Executing Group with DBObject [%s]", serializeToJsonSafely(commandObject)));
}
CommandResult commandResult = executeCommand(commandObject, getDb().getOptions());
@@ -1178,7 +1173,7 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware {
/**
* Create the specified collection using the provided options
*
*
* @param collectionName
* @param collectionOptions
* @return the collection that was created
@@ -1200,7 +1195,7 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware {
* Map the results of an ad-hoc query on the default MongoDB collection to an object using the template's converter
* <p/>
* The query document is specified as a standard DBObject and so is the fields specification.
*
*
* @param collectionName name of the collection to retrieve the objects from
* @param query the query document that specifies the criteria used to find a record
* @param fields the document that specifies the fields to be returned
@@ -1225,7 +1220,7 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware {
* The query document is specified as a standard DBObject and so is the fields specification.
* <p/>
* Can be overridden by subclasses.
*
*
* @param collectionName name of the collection to retrieve the objects from
* @param query the query document that specifies the criteria used to find a record
* @param fields the document that specifies the fields to be returned
@@ -1242,11 +1237,14 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware {
protected <S, T> List<T> doFind(String collectionName, DBObject query, DBObject fields, Class<S> entityClass,
CursorPreparer preparer, DbObjectCallback<T> objectCallback) {
MongoPersistentEntity<?> entity = mappingContext.getPersistentEntity(entityClass);
if (LOGGER.isDebugEnabled()) {
LOGGER.debug("find using query: " + query + " fields: " + fields + " for class: " + entityClass
+ " in collection: " + collectionName);
LOGGER.debug(String.format("find using query: %s fields: %s for class: %s in collection: %s",
serializeToJsonSafely(query), fields, entityClass, collectionName));
}
return executeFindMultiInternal(new FindCallback(mapper.getMappedObject(query, entity), fields), preparer,
objectCallback, collectionName);
}
@@ -1255,7 +1253,7 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware {
* Map the results of an ad-hoc query on the default MongoDB collection to a List using the template's converter.
* <p/>
* The query document is specified as a standard DBObject and so is the fields specification.
*
*
* @param collectionName name of the collection to retrieve the objects from
* @param query the query document that specifies the criteria used to find a record
* @param fields the document that specifies the fields to be returned
@@ -1294,7 +1292,7 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware {
* The first document that matches the query is returned and also removed from the collection in the database.
* <p/>
* The query document is specified as a standard DBObject and so is the fields specification.
*
*
* @param collectionName name of the collection to retrieve the objects from
* @param query the query document that specifies the criteria used to find a record
* @param entityClass the parameterized type of the returned list.
@@ -1341,7 +1339,7 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware {
/**
* Populates the id property of the saved object, if it's not set already.
*
*
* @param savedObject
* @param id
*/
@@ -1394,7 +1392,7 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware {
* <li>Execute the given {@link ConnectionCallback} for a {@link DBObject}.</li>
* <li>Apply the given {@link DbObjectCallback} to each of the {@link DBObject}s to obtain the result.</li>
* <ol>
*
*
* @param <T>
* @param collectionCallback the callback to retrieve the {@link DBObject} with
* @param objectCallback the {@link DbObjectCallback} to transform {@link DBObject}s into the actual domain type

View File

@@ -86,6 +86,8 @@ public class QueryMapper {
ids.add(convertId(id));
}
valueDbo.put(inKey, ids.toArray(new Object[ids.size()]));
} else if (valueDbo.containsField("$ne")) {
valueDbo.put("$ne", convertId(valueDbo.get("$ne")));
} else {
value = getMappedObject((DBObject) value, null);
}
@@ -99,11 +101,9 @@ public class QueryMapper {
BasicBSONList newConditions = new BasicBSONList();
Iterator<?> iter = conditions.iterator();
while (iter.hasNext()) {
newConditions.add(getMappedObject((DBObject) iter.next(), null));
newConditions.add(getMappedObject((DBObject) iter.next(), entity));
}
value = newConditions;
} else if (key.equals("$ne")) {
value = convertId(value);
}
newDbo.put(newKey, convertSimpleOrDBObject(value, null));

View File

@@ -514,9 +514,28 @@ public class Criteria implements CriteriaDefinition {
Criteria that = (Criteria) obj;
boolean keyEqual = this.key == null ? that.key == null : this.key.equals(that.key);
boolean criteriaEqual = this.criteria.equals(that.criteria);
boolean valueEqual = isEqual(this.isValue, that.isValue);
if (this.criteriaChain.size() != that.criteriaChain.size()) {
return false;
}
for (int i = 0; i < this.criteriaChain.size(); i++) {
Criteria left = this.criteriaChain.get(i);
Criteria right = that.criteriaChain.get(i);
if (!simpleCriteriaEquals(left, right)) {
return false;
}
}
return true;
}
private boolean simpleCriteriaEquals(Criteria left, Criteria right) {
boolean keyEqual = left.key == null ? right.key == null : left.key.equals(right.key);
boolean criteriaEqual = left.criteria.equals(right.criteria);
boolean valueEqual = isEqual(left.isValue, right.isValue);
return keyEqual && criteriaEqual && valueEqual;
}

View File

@@ -15,7 +15,7 @@
*/
package org.springframework.data.mongodb.core.query;
import static org.springframework.data.mongodb.core.SerializationUtils.*;
import static org.springframework.data.mongodb.core.query.SerializationUtils.*;
import static org.springframework.util.ObjectUtils.*;
import java.util.ArrayList;

View File

@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.data.mongodb.core;
package org.springframework.data.mongodb.core.query;
import java.util.Collection;
import java.util.Iterator;

View File

@@ -117,8 +117,11 @@ class MongoQueryCreator extends AbstractQueryCreator<Query, Criteria> {
}
PersistentPropertyPath<MongoPersistentProperty> path = context.getPersistentPropertyPath(part.getProperty());
return from(part.getType(), where(path.toDotPath(MongoPersistentProperty.PropertyToFieldNameConverter.INSTANCE)),
(PotentiallyConvertingIterator) iterator);
return new Criteria().andOperator(
base,
from(part.getType(), where(path.toDotPath(MongoPersistentProperty.PropertyToFieldNameConverter.INSTANCE)),
(PotentiallyConvertingIterator) iterator));
}
/*
@@ -265,4 +268,4 @@ class MongoQueryCreator extends AbstractQueryCreator<Query, Criteria> {
return source.replaceAll("\\*", ".*");
}
}
}

View File

@@ -14,7 +14,7 @@
<xsd:import namespace="http://www.springframework.org/schema/context"
schemaLocation="http://www.springframework.org/schema/context/spring-context.xsd" />
<xsd:import namespace="http://www.springframework.org/schema/data/repository"
schemaLocation="http://www.springframework.org/schema/data/repository/spring-repository.xsd" />
schemaLocation="http://www.springframework.org/schema/data/repository/spring-repository-1.0.xsd" />
<xsd:element name="mongo" type="mongoType">
<xsd:annotation>
@@ -44,8 +44,9 @@ The name of the mongo definition (by default "mongoDbFactory").]]></xsd:document
</xsd:attribute>
<xsd:attribute name="mongo-ref" type="mongoRef" use="optional">
<xsd:annotation>
<xsd:documentation>
The reference to a Mongo. Will default to 'mongo'.
<xsd:documentation><![CDATA[
The reference to a Mongo instance. If not configured a default com.mongodb.Mongo instance will be created.
]]>
</xsd:documentation>
</xsd:annotation>
</xsd:attribute>

View File

@@ -0,0 +1,81 @@
/*
* Copyright 2012 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.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.data.mongodb.core;
import static org.hamcrest.Matchers.*;
import static org.junit.Assert.*;
import com.mongodb.BasicDBList;
import com.mongodb.DBObject;
/**
* Helper classes to ease assertions on {@link DBObject}s.
*
* @author Oliver Gierke
*/
public abstract class DBObjectUtils {
private DBObjectUtils() {
}
/**
* Expects the field with the given key to be not {@literal null} and a {@link DBObject} in turn and returns it.
*
* @param source the {@link DBObject} to lookup the nested one
* @param key the key of the field to lokup the nested {@link DBObject}
* @return
*/
public static DBObject getAsDBObject(DBObject source, String key) {
return getTypedValue(source, key, DBObject.class);
}
/**
* Expects the field with the given key to be not {@literal null} and a {@link BasicDBList}.
*
* @param source the {@link DBObject} to lookup the {@link BasicDBList} in
* @param key the key of the field to find the {@link BasicDBList} in
* @return
*/
public static BasicDBList getAsDBList(DBObject source, String key) {
return getTypedValue(source, key, BasicDBList.class);
}
/**
* Expects the list element with the given index to be a non-{@literal null} {@link DBObject} and returns it.
*
* @param source the {@link BasicDBList} to look up the {@link DBObject} element in
* @param index the index of the element expected to contain a {@link DBObject}
* @return
*/
public static DBObject getAsDBObject(BasicDBList source, int index) {
assertThat(source.size(), greaterThanOrEqualTo(index + 1));
Object value = source.get(index);
assertThat(value, is(instanceOf(DBObject.class)));
return (DBObject) value;
}
@SuppressWarnings("unchecked")
private static <T> T getTypedValue(DBObject source, String key, Class<T> type) {
Object value = source.get(key);
assertThat(value, is(notNullValue()));
assertThat(value, is(instanceOf(type)));
return (T) value;
}
}

View File

@@ -1226,6 +1226,24 @@ public class MongoTemplateTests {
template.remove(query(where("id").is(id)), TypeWithMyId.class);
}
/**
* @see DATAMONGO-539
*/
@Test
public void removesObjectFromExplicitCollection() {
String collectionName = "explicit";
template.remove(new Query(), collectionName);
PersonWithConvertedId person = new PersonWithConvertedId();
person.name = "Dave";
template.save(person, collectionName);
assertThat(template.findAll(PersonWithConvertedId.class, collectionName).isEmpty(), is(false));
template.remove(person, collectionName);
assertThat(template.findAll(PersonWithConvertedId.class, collectionName).isEmpty(), is(true));
}
static class MyId {
String first;
@@ -1255,6 +1273,12 @@ public class MongoTemplateTests {
}
}
static class PersonWithConvertedId {
String id;
String name;
}
static enum DateTimeToDateConverter implements Converter<DateTime, Date> {
INSTANCE;

View File

@@ -17,12 +17,13 @@ package org.springframework.data.mongodb.core;
import static org.hamcrest.Matchers.*;
import static org.junit.Assert.*;
import static org.springframework.data.mongodb.core.SerializationUtils.*;
import static org.springframework.data.mongodb.core.query.SerializationUtils.*;
import java.util.Arrays;
import org.hamcrest.Matcher;
import org.junit.Test;
import org.springframework.data.mongodb.core.query.SerializationUtils;
import com.mongodb.BasicDBObject;
import com.mongodb.DBObject;

View File

@@ -15,10 +15,10 @@
*/
package org.springframework.data.mongodb.core.query;
import static org.junit.Assert.*;
import static org.hamcrest.CoreMatchers.*;
import static org.junit.Assert.*;
import org.junit.Test;
import org.springframework.data.mongodb.core.query.Criteria;
import com.mongodb.BasicDBObject;
import com.mongodb.DBObject;
@@ -51,4 +51,14 @@ public class CriteriaTests {
Criteria c = new Criteria("name").is("Bubba").and("age").lt(21);
assertEquals("{ \"name\" : \"Bubba\" , \"age\" : { \"$lt\" : 21}}", c.getCriteriaObject().toString());
}
@Test
public void equalIfCriteriaMatches() {
Criteria left = new Criteria("name").is("Foo").and("lastname").is("Bar");
Criteria right = new Criteria("name").is("Bar").and("lastname").is("Bar");
assertThat(left, is(not(right)));
assertThat(right, is(not(left)));
}
}

View File

@@ -19,9 +19,12 @@ import static org.hamcrest.Matchers.*;
import static org.junit.Assert.*;
import static org.springframework.data.mongodb.core.query.Criteria.*;
import static org.springframework.data.mongodb.core.query.Query.*;
import static org.springframework.data.mongodb.core.DBObjectUtils.*;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import org.bson.types.ObjectId;
import org.junit.Before;
@@ -48,7 +51,6 @@ import com.mongodb.QueryBuilder;
* @author Oliver Gierke
*/
@RunWith(MockitoJUnitRunner.class)
@SuppressWarnings("unused")
public class QueryMapperUnitTests {
QueryMapper mapper;
@@ -211,6 +213,45 @@ public class QueryMapperUnitTests {
assertThat(((DBObject) result.get("nested")).get("id"), is(instanceOf(String.class)));
}
/**
* @see DATAMONGO-493
*/
@Test
public void doesNotTranslateNonIdPropertiesFor$NeCriteria() {
ObjectId accidentallyAnObjectId = new ObjectId();
Query query = Query.query(Criteria.where("id").is("id_value").and("publishers")
.ne(accidentallyAnObjectId.toString()));
DBObject dbObject = mapper.getMappedObject(query.getQueryObject(), context.getPersistentEntity(UserEntity.class));
assertThat(dbObject.get("publishers"), is(instanceOf(DBObject.class)));
DBObject publishers = (DBObject) dbObject.get("publishers");
assertThat(publishers.containsField("$ne"), is(true));
assertThat(publishers.get("$ne"), is(instanceOf(String.class)));
}
/**
* @see DATAMONGO-494
*/
@Test
public void usesEntityMetadataInOr() {
Query query = query(new Criteria().orOperator(where("foo").is("bar")));
DBObject result = mapper.getMappedObject(query.getQueryObject(), context.getPersistentEntity(Sample.class));
assertThat(result.keySet(), hasSize(1));
assertThat(result.keySet(), hasItem("$or"));
BasicDBList ors = getAsDBList(result, "$or");
assertThat(ors, hasSize(1));
DBObject criterias = getAsDBObject(ors, 0);
assertThat(criterias.keySet(), hasSize(1));
assertThat(criterias.get("_id"), is(notNullValue()));
assertThat(criterias.get("foo"), is(nullValue()));
}
class IdWrapper {
Object id;
}
@@ -236,4 +277,9 @@ public class QueryMapperUnitTests {
enum Enum {
INSTANCE;
}
class UserEntity {
String id;
List<String> publishers = new ArrayList<String>();
}
}

View File

@@ -432,4 +432,21 @@ public abstract class AbstractPersonRepositoryIntegrationTests {
List<Person> result = repository.findByCreatedAtLessThanManually(boyd.createdAt);
assertThat(result.isEmpty(), is(false));
}
}
/**
* @see DATAMONGO-521
*/
@Test
public void executesAndQueryCorrectly() {
List<Person> result = repository.findByFirstnameAndLastname("Dave", "Matthews");
assertThat(result, hasSize(1));
assertThat(result, hasItem(dave));
result = repository.findByFirstnameAndLastname("Oliver August", "Matthews");
assertThat(result, hasSize(1));
assertThat(result, hasItem(oliver));
}
}

View File

@@ -106,6 +106,8 @@ public interface PersonRepository extends MongoRepository<Person, String>, Query
*/
List<Person> findByFirstnameNotIn(Collection<String> firstnames);
List<Person> findByFirstnameAndLastname(String firstname, String lastname);
/**
* Returns all {@link Person}s with an age between the two given values.
*

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2010 the original author or authors.
* Copyright 2010-2012 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.

View File

@@ -21,6 +21,7 @@ import static org.junit.Assert.*;
import java.util.ArrayList;
import java.util.List;
import org.hamcrest.Matcher;
import org.junit.After;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -44,11 +45,9 @@ import com.mongodb.MongoException;
@ContextConfiguration
public class RepositoryIndexCreationIntegrationTests {
@Autowired
MongoOperations operations;
@Autowired MongoOperations operations;
@Autowired
PersonRepository repository;
@Autowired PersonRepository repository;
@After
public void tearDown() {
@@ -72,13 +71,18 @@ public class RepositoryIndexCreationIntegrationTests {
public void testname() {
operations.execute(Person.class, new CollectionCallback<Void>() {
@SuppressWarnings("unchecked")
public Void doInCollection(DBCollection collection) throws MongoException, DataAccessException {
List<DBObject> indexInfo = collection.getIndexInfo();
assertThat(indexInfo.isEmpty(), is(false));
assertThat(indexInfo.size(), is(greaterThan(2)));
assertThat(getIndexNamesFrom(indexInfo), hasItems("findByLastnameLike", "findByFirstnameLike"));
Matcher<String> lastnameIndex = startsWith("findByLastname");
Matcher<String> firstnameIndex = startsWith("findByFirstname");
Matcher<Iterable<String>> hasItems = hasItems(lastnameIndex, firstnameIndex);
assertThat(getIndexNamesFrom(indexInfo), hasItems);
return null;
}
});

View File

@@ -97,7 +97,8 @@ public class MongoQueryCreatorUnitTests {
getAccessor(converter, "Oliver", person), context);
Query query = creator.createQuery();
assertThat(query, is(query(where("firstName").is("Oliver").and("friend").is(person))));
Criteria criteria = new Criteria().andOperator(where("firstName").is("Oliver"), where("friend").is(person));
assertThat(query, is(query(criteria)));
}
@Test
@@ -222,7 +223,7 @@ public class MongoQueryCreatorUnitTests {
}
/**
* @see DATAMONGO
* @see DATAMONGO-413
*/
@Test
public void createsOrQueryCorrectly() {

View File

@@ -12,17 +12,17 @@
<title>Knowing Spring</title>
<para>Spring Data uses Spring framework's <ulink
url="http://static.springframework.org/spring/docs/3.0.x/reference/spring-core.html">core</ulink>
url="http://static.springframework.org/spring/docs/3.0.x/reference/html/spring-core.html">core</ulink>
functionality, such as the <ulink
url="http://static.springframework.org/spring/docs/3.0.x/reference/beans.html">IoC</ulink>
url="http://static.springframework.org/spring/docs/3.0.x/reference/html/beans.html">IoC</ulink>
container, <ulink
url="http://static.springsource.org/spring/docs/3.0.x/reference/validation.html#core-convert">type
conv ersion system</ulink>, <ulink
url="http://static.springsource.org/spring/docs/3.0.x/reference/expressions.html">expression
url="http://static.springsource.org/spring/docs/3.0.x/reference/html/validation.html#core-convert">type
conversion system</ulink>, <ulink
url="http://static.springsource.org/spring/docs/3.0.x/reference/html/expressions.html">expression
language</ulink>, <ulink
url="http://static.springsource.org/spring/docs/3.0.x/reference/jmx.html">JMX
url="http://static.springsource.org/spring/docs/3.0.x/reference/html/jmx.html">JMX
integration</ulink>, and portable <ulink
url="http://static.springsource.org/spring/docs/3.0.x/reference/dao.html#dao-exceptions">DAO
url="http://static.springsource.org/spring/docs/3.0.x/reference/html/dao.html#dao-exceptions">DAO
exception hierarchy</ulink>. While it is not important to know the
Spring APIs, understanding the concepts behind them is. At a minimum,
the idea behind IoC should be familiar for whatever IoC container you

View File

@@ -1,6 +1,20 @@
Spring Data Document Changelog
=============================================
Changes in version 1.0.4.RELEASE MongoDB (2012-08-24)
-----------------------------------------------------
** Bug
* [DATAMONGO-493] - Criteria.ne() method converts all value into ObjectId
* [DATAMONGO-494] - $or/$nor expressions do not consider entity class mapping
* [DATAMONGO-495] - JSON can't serialize Enum when printing Query in DEBUG message
** Improvement
* [DATAMONGO-499] - Namespace XSDs of current release version should refer to repositories XSD in version 1.0
** Task
* [DATAMONGO-514] - Release 1.0.4.
Changes in version 1.0.3.RELEASE MongoDB (2012-07-23)
-----------------------------------------------------
** Bug
* [DATAMONGO-467] - String @id field is not mapped to ObjectId when using QueryDSL ".id" path
* [DATAMONGO-469] - Query creation from method names using AND criteria does not work anymore