Compare commits
23 Commits
1.3.0.M1
...
1.2.1.RELE
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
928b5a7742 | ||
|
|
118a52a8d6 | ||
|
|
b47e8ca3da | ||
|
|
8527d6eb43 | ||
|
|
d645c778c3 | ||
|
|
5c47f1ae9e | ||
|
|
9f324bac19 | ||
|
|
186caba1ac | ||
|
|
2ebb7e801d | ||
|
|
a932f3474e | ||
|
|
e992456532 | ||
|
|
7b34c5cac4 | ||
|
|
16baf00f5e | ||
|
|
61a2c56a27 | ||
|
|
e62437b64a | ||
|
|
e9a7e887be | ||
|
|
b91a66f6f9 | ||
|
|
a047e54e5a | ||
|
|
8197ff57c8 | ||
|
|
a2136719e1 | ||
|
|
7bcf142c8d | ||
|
|
d50d03a80e | ||
|
|
ba894a4511 |
152
README.md
152
README.md
@@ -1,26 +1,33 @@
|
||||
# Spring Data MongoDB
|
||||
Spring Data MongoDB
|
||||
======================
|
||||
|
||||
The primary goal of the [Spring Data](http://www.springsource.org/spring-data) project is to make it easier to build Spring-powered applications that use new data access technologies such as non-relational databases, map-reduce frameworks, and cloud based data services.
|
||||
|
||||
The Spring Data MongoDB project aims to provide a familiar and consistent Spring-based programming model for new datastores while retaining store-specific features and capabilities. The Spring Data MongoDB project provides integration with the MongoDB document database. Key functional areas of Spring Data MongoDB are a POJO centric model for interacting with a MongoDB DBCollection and easily writing a repository style data access layer.
|
||||
The Spring Data MongoDB aims to provide a familiar and consistent Spring-based programming model for for new datastores while retaining store-specific features and capabilities. The Spring Data MongoDB project provides integration with the MongoDB document database. Key functional areas of Spring Data MongoDB are a POJO centric model for interacting with a MongoDB DBCollection and easily writing a Repository style data access layer
|
||||
|
||||
## Getting Help
|
||||
Getting Help
|
||||
------------
|
||||
|
||||
For a comprehensive treatmet of all the Spring Data MongoDB features, please refer to:
|
||||
For a comprehensive treatmet of all the Spring Data MongoDB features, please refer to the The [User Guide](http://static.springsource.org/spring-data/data-mongodb/docs/current/reference/html/)
|
||||
|
||||
* the [User Guide](http://static.springsource.org/spring-data/data-mongodb/docs/current/reference/html/)
|
||||
* the [JavaDocs](http://static.springsource.org/spring-data/data-mongodb/docs/current/api/) have extensive comments in them as well.
|
||||
* the home page of [Spring Data MongoDB](http://www.springsource.org/spring-data/mongodb) contains links to articles and other resources.
|
||||
* for more detailed questions, use the [forum](http://forum.springsource.org/forumdisplay.php?f=80).
|
||||
The [JavaDocs](http://static.springsource.org/spring-data/data-mongodb/docs/current/api/) have extensive comments in them as well.
|
||||
|
||||
The home page of [Spring Data MongoDB](http://www.springsource.org/spring-data/mongodb) contains links to articles and other resources.
|
||||
|
||||
For more detailed questions, use the [forum](http://forum.springsource.org/forumdisplay.php?f=80).
|
||||
|
||||
If you are new to Spring as well as to Spring Data, look for information about [Spring projects](http://www.springsource.org/projects).
|
||||
|
||||
|
||||
## Quick Start
|
||||
Quick Start
|
||||
-----------
|
||||
|
||||
### Maven configuration
|
||||
## MongoDB
|
||||
|
||||
Add the Maven dependency:
|
||||
For those in a hurry:
|
||||
|
||||
|
||||
* Download the jar through Maven:
|
||||
|
||||
```xml
|
||||
<dependency>
|
||||
@@ -30,39 +37,60 @@ Add the Maven dependency:
|
||||
</dependency>
|
||||
```
|
||||
|
||||
If you'd rather like the latest snapshots of the upcoming major version, use our Maven snapshot repository and declare the appropriate dependency version.
|
||||
|
||||
```xml
|
||||
<dependency>
|
||||
<groupId>org.springframework.data</groupId>
|
||||
<artifactId>spring-data-mongodb</artifactId>
|
||||
<version>1.2.1.RELEASE</version>
|
||||
</dependency>
|
||||
|
||||
<repository>
|
||||
<id>spring-libs-snapshot</id>
|
||||
<name>Spring Snapshot Repository</name>
|
||||
<url>http://repo.springsource.org/libs-snapshot</url>
|
||||
</repository>
|
||||
```
|
||||
|
||||
### MongoTemplate
|
||||
|
||||
MongoTemplate is the central support class for Mongo database operations. It provides:
|
||||
MongoTemplate is the central support class for Mongo database operations. It provides
|
||||
|
||||
* Basic POJO mapping support to and from BSON
|
||||
* Convenience methods to interact with the store (insert object, update objects) and MongoDB specific ones (geo-spatial operations, upserts, map-reduce etc.)
|
||||
* Connection affinity callback
|
||||
* Connection Affinity callback
|
||||
* Exception translation into Spring's [technology agnostic DAO exception hierarchy](http://static.springsource.org/spring/docs/3.0.x/spring-framework-reference/html/dao.html#dao-exceptions).
|
||||
|
||||
### Spring Data repositories
|
||||
Future plans are to support optional logging and/or exception throwing based on WriteResult return value, common map-reduce operations, GridFS operations. A simple API for partial document updates is also planned.
|
||||
|
||||
To simplify the creation of data repositories Sprin Data MongoDB provides a generic repository programming model. It will automatically create a repository proxy for you that adds implementations of finder methods you specify on an interface.
|
||||
### Easy Data Repository generation
|
||||
|
||||
For example, given a `Person` class with first and last name properties, a `PersonRepository` interface that can query for `Person` by last name and when the first name matches a like expression is shown below:
|
||||
To simplify the creation of data repositories a generic `Repository` interface and default implementation is provided. Furthermore, Spring will automatically create a Repository implementation for you that adds implementations of finder methods you specify on an interface.
|
||||
|
||||
The Repository interface is
|
||||
|
||||
```java
|
||||
public interface PersonRepository extends CrudRepository<Person, Long> {
|
||||
public interface Repository<T, ID extends Serializable> {
|
||||
|
||||
T save(T entity);
|
||||
|
||||
List<T> save(Iterable<? extends T> entities);
|
||||
|
||||
T findById(ID id);
|
||||
|
||||
boolean exists(ID id);
|
||||
|
||||
List<T> findAll();
|
||||
|
||||
Long count();
|
||||
|
||||
void delete(T entity);
|
||||
|
||||
void delete(Iterable<? extends T> entities);
|
||||
|
||||
void deleteAll();
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
The `MongoRepository` extends `Repository` and will in future add more Mongo specific methods.
|
||||
|
||||
```java
|
||||
public interface MongoRepository<T, ID extends Serializable> extends Repository<T, ID> {
|
||||
}
|
||||
```
|
||||
|
||||
`SimpleMongoRepository` is the out of the box implementation of the `MongoRepository` you can use for basid CRUD operations.
|
||||
|
||||
To go beyond basic CRUD, extend the `MongoRepository` interface and supply your own finder methods that follow simple naming conventions such that they can be easily converted into queries.
|
||||
|
||||
For example, given a `Person` class with first and last name properties, a `PersonRepository` interface that can query for `Person` by last name and when the first name matches a regular expression is shown below
|
||||
|
||||
```java
|
||||
public interface PersonRepository extends MongoRepository<Person, Long> {
|
||||
|
||||
List<Person> findByLastname(String lastname);
|
||||
|
||||
@@ -70,55 +98,31 @@ public interface PersonRepository extends CrudRepository<Person, Long> {
|
||||
}
|
||||
```
|
||||
|
||||
The queries issued on execution will be derived from the method name. Exending `CrudRepository` causes CRUD methods being pulled into the interface so that you can easily save and find single entities and collections of them.
|
||||
|
||||
You can have Spring automatically create a proxy for the interface by using the following JavaConfig:
|
||||
|
||||
```java
|
||||
@Configuration
|
||||
@EnableMongoRepositories
|
||||
class ApplicationConfig extends AbstractMongoConfiguration {
|
||||
|
||||
@Override
|
||||
public Mongo mongo() throws Exception {
|
||||
return new Mongo();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getDatabaseName() {
|
||||
return "springdata";
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
This sets up a connection to a local MongoDB instance and enables the detection of Spring Data repositories (through `@EnableMongoRepositories`). The same configuration would look like this in XML:
|
||||
You can have Spring automatically create a proxy for the interface as shown below:
|
||||
|
||||
```xml
|
||||
<bean id="template" class="org.springframework.data.document.mongodb.MongoTemplate">
|
||||
<constructor-arg>
|
||||
<bean class="com.mongodb.Mongo">
|
||||
<constructor-arg value="localhost" />
|
||||
<constructor-arg value="27017" />
|
||||
</bean>
|
||||
</constructor-arg>
|
||||
<constructor-arg value="database" />
|
||||
<constructor-arg>
|
||||
<bean class="com.mongodb.Mongo">
|
||||
<constructor-arg value="localhost" />
|
||||
<constructor-arg value="27017" />
|
||||
</bean>
|
||||
</constructor-arg>
|
||||
<constructor-arg value="database" />
|
||||
<property name="defaultCollectionName" value="springdata" />
|
||||
</bean>
|
||||
|
||||
<mongo:repositories base-package="com.acme.repository" />
|
||||
```
|
||||
|
||||
This will find the repository interface and register a proxy object in the container. You can use it as shown below:
|
||||
This will find the repository interface and register a proxy object in the container. You can use it as shown below:
|
||||
|
||||
```java
|
||||
``java
|
||||
@Service
|
||||
public class MyService {
|
||||
|
||||
private final PersonRepository repository;
|
||||
|
||||
@Autowired
|
||||
public MyService(PersonRepository repository) {
|
||||
this.repository = repository;
|
||||
}
|
||||
private final PersonRepository repository;
|
||||
|
||||
public void doWork() {
|
||||
|
||||
@@ -130,12 +134,16 @@ public class MyService {
|
||||
person = repository.save(person);
|
||||
|
||||
List<Person> lastNameResults = repository.findByLastname("Gierke");
|
||||
|
||||
List<Person> firstNameResults = repository.findByFirstnameLike("Oli*");
|
||||
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Contributing to Spring Data
|
||||
|
||||
Contributing to Spring Data
|
||||
---------------------------
|
||||
|
||||
Here are some ways for you to get involved in the community:
|
||||
|
||||
|
||||
13
pom.xml
13
pom.xml
@@ -5,7 +5,7 @@
|
||||
|
||||
<groupId>org.springframework.data</groupId>
|
||||
<artifactId>spring-data-mongodb-parent</artifactId>
|
||||
<version>1.3.0.M1</version>
|
||||
<version>1.2.1.RELEASE</version>
|
||||
<packaging>pom</packaging>
|
||||
|
||||
<name>Spring Data MongoDB</name>
|
||||
@@ -15,7 +15,7 @@
|
||||
<parent>
|
||||
<groupId>org.springframework.data.build</groupId>
|
||||
<artifactId>spring-data-parent</artifactId>
|
||||
<version>1.1.0.RELEASE</version>
|
||||
<version>1.0.3.RELEASE</version>
|
||||
<relativePath>../spring-data-build/parent/pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
@@ -29,7 +29,7 @@
|
||||
<properties>
|
||||
<project.type>multi</project.type>
|
||||
<dist.id>spring-data-mongodb</dist.id>
|
||||
<springdata.commons>1.6.0.M1</springdata.commons>
|
||||
<springdata.commons>1.5.1.RELEASE</springdata.commons>
|
||||
<mongo>2.10.1</mongo>
|
||||
</properties>
|
||||
|
||||
@@ -88,12 +88,5 @@
|
||||
<version>${mongo}</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<repositories>
|
||||
<repository>
|
||||
<id>spring-lib-milestone</id>
|
||||
<url>http://repo.springsource.org/libs-milestone-local</url>
|
||||
</repository>
|
||||
</repositories>
|
||||
|
||||
</project>
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
<parent>
|
||||
<groupId>org.springframework.data</groupId>
|
||||
<artifactId>spring-data-mongodb-parent</artifactId>
|
||||
<version>1.3.0.M1</version>
|
||||
<version>1.2.1.RELEASE</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
@@ -52,7 +52,7 @@
|
||||
<dependency>
|
||||
<groupId>org.springframework.data</groupId>
|
||||
<artifactId>spring-data-mongodb</artifactId>
|
||||
<version>1.3.0.M1</version>
|
||||
<version>1.2.1.RELEASE</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
<parent>
|
||||
<groupId>org.springframework.data</groupId>
|
||||
<artifactId>spring-data-mongodb-parent</artifactId>
|
||||
<version>1.3.0.M1</version>
|
||||
<version>1.2.1.RELEASE</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<groupId>org.springframework.data</groupId>
|
||||
<artifactId>spring-data-mongodb-parent</artifactId>
|
||||
<version>1.3.0.M1</version>
|
||||
<version>1.2.1.RELEASE</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
||||
<context version="7.1.7.187">
|
||||
<context version="7.0.3.1152">
|
||||
<scope name="spring-data-mongodb" type="Project">
|
||||
<element name="Filter" type="TypeFilterReferenceOverridden">
|
||||
<element name="org.springframework.data.mongodb.**" type="IncludeTypePattern"/>
|
||||
@@ -10,7 +10,6 @@
|
||||
<element name="**.config.**" type="WeakTypePattern"/>
|
||||
</element>
|
||||
<dependency type="AllowedDependency" toName="Project|spring-data-mongodb::Layer|Core"/>
|
||||
<dependency type="AllowedDependency" toName="Project|spring-data-mongodb::Layer|GridFS"/>
|
||||
<dependency type="AllowedDependency" toName="Project|spring-data-mongodb::Layer|Monitoring"/>
|
||||
<dependency type="AllowedDependency" toName="Project|spring-data-mongodb::Layer|Repositories"/>
|
||||
</element>
|
||||
@@ -94,12 +93,6 @@
|
||||
<dependency type="AllowedDependency" toName="Project|spring-data-mongodb::Layer|Core::Subsystem|Query"/>
|
||||
</element>
|
||||
</element>
|
||||
<element name="API" type="Subsystem">
|
||||
<element name="Assignment" type="TypeFilter">
|
||||
<element name="org.springframework.data.mongodb.*" type="IncludeTypePattern"/>
|
||||
</element>
|
||||
<stereotype name="Public"/>
|
||||
</element>
|
||||
</architecture>
|
||||
<workspace>
|
||||
<element name="src/main/java" type="JavaRootDirectory">
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
<parent>
|
||||
<groupId>org.springframework.data</groupId>
|
||||
<artifactId>spring-data-mongodb-parent</artifactId>
|
||||
<version>1.3.0.M1</version>
|
||||
<version>1.2.1.RELEASE</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
@@ -141,8 +141,8 @@
|
||||
|
||||
<plugin>
|
||||
<groupId>com.mysema.maven</groupId>
|
||||
<artifactId>apt-maven-plugin</artifactId>
|
||||
<version>1.0.8</version>
|
||||
<artifactId>maven-apt-plugin</artifactId>
|
||||
<version>1.0.4</version>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>com.mysema.querydsl</groupId>
|
||||
|
||||
@@ -13,9 +13,10 @@
|
||||
* 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;
|
||||
|
||||
import org.springframework.dao.DataIntegrityViolationException;
|
||||
import org.springframework.data.mongodb.core.MongoActionOperation;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
import com.mongodb.WriteResult;
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2011-2013 the original author or authors.
|
||||
* Copyright 2011-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.
|
||||
@@ -32,7 +32,6 @@ import org.springframework.data.mongodb.core.MongoTemplate;
|
||||
import org.springframework.data.mongodb.core.SimpleMongoDbFactory;
|
||||
import org.springframework.data.mongodb.core.convert.CustomConversions;
|
||||
import org.springframework.data.mongodb.core.convert.MappingMongoConverter;
|
||||
import org.springframework.data.mongodb.core.mapping.CamelCaseAbbreviatingFieldNamingStrategy;
|
||||
import org.springframework.data.mongodb.core.mapping.Document;
|
||||
import org.springframework.data.mongodb.core.mapping.MongoMappingContext;
|
||||
import org.springframework.data.support.CachingIsNewStrategyFactory;
|
||||
@@ -59,12 +58,12 @@ public abstract class AbstractMongoConfiguration {
|
||||
protected abstract String getDatabaseName();
|
||||
|
||||
/**
|
||||
* Return the {@link Mongo} instance to connect to. Annotate with {@link Bean} in case you want to expose a
|
||||
* {@link Mongo} instance to the {@link org.springframework.context.ApplicationContext}.
|
||||
* Return the {@link Mongo} instance to connect to.
|
||||
*
|
||||
* @return
|
||||
* @throws Exception
|
||||
*/
|
||||
@Bean
|
||||
public abstract Mongo mongo() throws Exception;
|
||||
|
||||
/**
|
||||
@@ -135,10 +134,7 @@ public abstract class AbstractMongoConfiguration {
|
||||
MongoMappingContext mappingContext = new MongoMappingContext();
|
||||
mappingContext.setInitialEntitySet(getInitialEntitySet());
|
||||
mappingContext.setSimpleTypeHolder(customConversions().getSimpleTypeHolder());
|
||||
|
||||
if (abbreviateFieldNames()) {
|
||||
mappingContext.setFieldNamingStrategy(new CamelCaseAbbreviatingFieldNamingStrategy());
|
||||
}
|
||||
mappingContext.initialize();
|
||||
|
||||
return mappingContext;
|
||||
}
|
||||
@@ -209,15 +205,4 @@ public abstract class AbstractMongoConfiguration {
|
||||
|
||||
return initialEntitySet;
|
||||
}
|
||||
|
||||
/**
|
||||
* Configures whether to abbreviate field names for domain objects by configuring a
|
||||
* {@link CamelCaseAbbreviatingFieldNamingStrategy} on the {@link MongoMappingContext} instance created. For advanced
|
||||
* customization needs, consider overriding {@link #mappingMongoConverter()}.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
protected boolean abbreviateFieldNames() {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
/*
|
||||
* Copyright 2011-2013 the original author or authors.
|
||||
* Copyright (c) 2011 by the original author(s).
|
||||
*
|
||||
* 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,
|
||||
@@ -13,14 +13,11 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.data.mongodb.config;
|
||||
|
||||
/**
|
||||
* Constants to declare bean names used by the namespace configuration.
|
||||
*
|
||||
* @author Jon Brisbin
|
||||
* @author Oliver Gierke
|
||||
* @author Martin Baumgartner
|
||||
* @author Jon Brisbin <jbrisbin@vmware.com>
|
||||
*/
|
||||
public abstract class BeanNames {
|
||||
|
||||
@@ -31,6 +28,4 @@ public abstract class BeanNames {
|
||||
static final String VALIDATING_EVENT_LISTENER = "validatingMongoEventListener";
|
||||
static final String IS_NEW_STRATEGY_FACTORY = "isNewStrategyFactory";
|
||||
static final String DEFAULT_CONVERTER_BEAN_NAME = "mappingConverter";
|
||||
static final String MONGO_TEMPLATE = "mongoTemplate";
|
||||
static final String GRID_FS_TEMPLATE = "gridFsTemplate";
|
||||
}
|
||||
|
||||
@@ -1,78 +0,0 @@
|
||||
/*
|
||||
* Copyright 2013 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.config;
|
||||
|
||||
import org.springframework.beans.factory.BeanDefinitionStoreException;
|
||||
import org.springframework.beans.factory.config.BeanDefinition;
|
||||
import org.springframework.beans.factory.support.AbstractBeanDefinition;
|
||||
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
|
||||
import org.springframework.beans.factory.xml.AbstractBeanDefinitionParser;
|
||||
import org.springframework.beans.factory.xml.BeanDefinitionParser;
|
||||
import org.springframework.beans.factory.xml.ParserContext;
|
||||
import org.springframework.data.config.BeanComponentDefinitionBuilder;
|
||||
import org.springframework.data.mongodb.gridfs.GridFsTemplate;
|
||||
import org.springframework.util.StringUtils;
|
||||
import org.w3c.dom.Element;
|
||||
|
||||
/**
|
||||
* {@link BeanDefinitionParser} to parse {@code gridFsTemplate} elements into {@link BeanDefinition}s.
|
||||
*
|
||||
* @author Martin Baumgartner
|
||||
*/
|
||||
class GridFsTemplateParser extends AbstractBeanDefinitionParser {
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.beans.factory.xml.AbstractBeanDefinitionParser#resolveId(org.w3c.dom.Element, org.springframework.beans.factory.support.AbstractBeanDefinition, org.springframework.beans.factory.xml.ParserContext)
|
||||
*/
|
||||
@Override
|
||||
protected String resolveId(Element element, AbstractBeanDefinition definition, ParserContext parserContext)
|
||||
throws BeanDefinitionStoreException {
|
||||
|
||||
String id = super.resolveId(element, definition, parserContext);
|
||||
return StringUtils.hasText(id) ? id : BeanNames.GRID_FS_TEMPLATE;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.beans.factory.xml.AbstractBeanDefinitionParser#parseInternal(org.w3c.dom.Element, org.springframework.beans.factory.xml.ParserContext)
|
||||
*/
|
||||
@Override
|
||||
protected AbstractBeanDefinition parseInternal(Element element, ParserContext parserContext) {
|
||||
|
||||
BeanComponentDefinitionBuilder helper = new BeanComponentDefinitionBuilder(element, parserContext);
|
||||
|
||||
String converterRef = element.getAttribute("converter-ref");
|
||||
String dbFactoryRef = element.getAttribute("db-factory-ref");
|
||||
|
||||
BeanDefinitionBuilder gridFsTemplateBuilder = BeanDefinitionBuilder.genericBeanDefinition(GridFsTemplate.class);
|
||||
|
||||
if (StringUtils.hasText(dbFactoryRef)) {
|
||||
gridFsTemplateBuilder.addConstructorArgReference(dbFactoryRef);
|
||||
} else {
|
||||
gridFsTemplateBuilder.addConstructorArgReference(BeanNames.DB_FACTORY);
|
||||
}
|
||||
|
||||
if (StringUtils.hasText(converterRef)) {
|
||||
gridFsTemplateBuilder.addConstructorArgReference(converterRef);
|
||||
} else {
|
||||
gridFsTemplateBuilder.addConstructorArgReference(BeanNames.DEFAULT_CONVERTER_BEAN_NAME);
|
||||
}
|
||||
|
||||
return (AbstractBeanDefinition) helper.getComponentIdButFallback(gridFsTemplateBuilder, BeanNames.GRID_FS_TEMPLATE)
|
||||
.getBeanDefinition();
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2011-2013 the original author or authors.
|
||||
* Copyright 2011-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.
|
||||
@@ -54,7 +54,6 @@ import org.springframework.data.mapping.context.MappingContextIsNewStrategyFacto
|
||||
import org.springframework.data.mongodb.core.convert.CustomConversions;
|
||||
import org.springframework.data.mongodb.core.convert.MappingMongoConverter;
|
||||
import org.springframework.data.mongodb.core.index.MongoPersistentEntityIndexCreator;
|
||||
import org.springframework.data.mongodb.core.mapping.CamelCaseAbbreviatingFieldNamingStrategy;
|
||||
import org.springframework.data.mongodb.core.mapping.Document;
|
||||
import org.springframework.data.mongodb.core.mapping.MongoMappingContext;
|
||||
import org.springframework.data.mongodb.core.mapping.event.ValidatingMongoEventListener;
|
||||
@@ -119,7 +118,6 @@ public class MappingMongoConverterParser implements BeanDefinitionParser {
|
||||
.genericBeanDefinition(MongoPersistentEntityIndexCreator.class);
|
||||
indexHelperBuilder.addConstructorArgReference(ctxRef);
|
||||
indexHelperBuilder.addConstructorArgReference(dbFactoryRef);
|
||||
indexHelperBuilder.addDependsOn(ctxRef);
|
||||
|
||||
parserContext.registerBeanComponent(new BeanComponentDefinition(indexHelperBuilder.getBeanDefinition(),
|
||||
INDEX_HELPER));
|
||||
@@ -202,12 +200,6 @@ public class MappingMongoConverterParser implements BeanDefinitionParser {
|
||||
mappingContextBuilder.addPropertyValue("simpleTypeHolder", simpleTypesDefinition);
|
||||
}
|
||||
|
||||
String abbreviateFieldNames = element.getAttribute("abbreviate-field-names");
|
||||
if ("true".equals(abbreviateFieldNames)) {
|
||||
mappingContextBuilder.addPropertyValue("fieldNamingStrategy", new RootBeanDefinition(
|
||||
CamelCaseAbbreviatingFieldNamingStrategy.class));
|
||||
}
|
||||
|
||||
ctxRef = converterId + "." + MAPPING_CONTEXT;
|
||||
|
||||
parserContext.registerBeanComponent(componentDefinitionBuilder.getComponent(mappingContextBuilder, ctxRef));
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2011-2013 the original author or authors.
|
||||
* Copyright 2011-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.
|
||||
@@ -24,7 +24,6 @@ import org.springframework.data.repository.config.RepositoryConfigurationExtensi
|
||||
* {@link org.springframework.beans.factory.xml.NamespaceHandler} for Mongo DB configuration.
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
* @author Martin Baumgartner
|
||||
*/
|
||||
public class MongoNamespaceHandler extends NamespaceHandlerSupport {
|
||||
|
||||
@@ -43,7 +42,5 @@ public class MongoNamespaceHandler extends NamespaceHandlerSupport {
|
||||
registerBeanDefinitionParser("db-factory", new MongoDbFactoryParser());
|
||||
registerBeanDefinitionParser("jmx", new MongoJmxParser());
|
||||
registerBeanDefinitionParser("auditing", new MongoAuditingBeanDefinitionParser());
|
||||
registerBeanDefinitionParser("template", new MongoTemplateParser());
|
||||
registerBeanDefinitionParser("gridFsTemplate", new GridFsTemplateParser());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,86 +0,0 @@
|
||||
/*
|
||||
* Copyright 2011-2013 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.config;
|
||||
|
||||
import static org.springframework.data.config.ParsingUtils.*;
|
||||
import static org.springframework.data.mongodb.config.MongoParsingUtils.*;
|
||||
|
||||
import org.springframework.beans.factory.BeanDefinitionStoreException;
|
||||
import org.springframework.beans.factory.config.BeanDefinition;
|
||||
import org.springframework.beans.factory.parsing.BeanComponentDefinition;
|
||||
import org.springframework.beans.factory.support.AbstractBeanDefinition;
|
||||
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
|
||||
import org.springframework.beans.factory.xml.AbstractBeanDefinitionParser;
|
||||
import org.springframework.beans.factory.xml.BeanDefinitionParser;
|
||||
import org.springframework.beans.factory.xml.ParserContext;
|
||||
import org.springframework.data.config.BeanComponentDefinitionBuilder;
|
||||
import org.springframework.data.mongodb.core.MongoTemplate;
|
||||
import org.springframework.util.StringUtils;
|
||||
import org.w3c.dom.Element;
|
||||
|
||||
/**
|
||||
* {@link BeanDefinitionParser} to parse {@code template} elements into {@link BeanDefinition}s.
|
||||
*
|
||||
* @author Martin Baumgartner
|
||||
*/
|
||||
class MongoTemplateParser extends AbstractBeanDefinitionParser {
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.beans.factory.xml.AbstractBeanDefinitionParser#resolveId(org.w3c.dom.Element, org.springframework.beans.factory.support.AbstractBeanDefinition, org.springframework.beans.factory.xml.ParserContext)
|
||||
*/
|
||||
@Override
|
||||
protected String resolveId(Element element, AbstractBeanDefinition definition, ParserContext parserContext)
|
||||
throws BeanDefinitionStoreException {
|
||||
|
||||
String id = super.resolveId(element, definition, parserContext);
|
||||
return StringUtils.hasText(id) ? id : BeanNames.MONGO_TEMPLATE;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.beans.factory.xml.AbstractBeanDefinitionParser#parseInternal(org.w3c.dom.Element, org.springframework.beans.factory.xml.ParserContext)
|
||||
*/
|
||||
@Override
|
||||
protected AbstractBeanDefinition parseInternal(Element element, ParserContext parserContext) {
|
||||
|
||||
BeanComponentDefinitionBuilder helper = new BeanComponentDefinitionBuilder(element, parserContext);
|
||||
|
||||
String converterRef = element.getAttribute("converter-ref");
|
||||
String dbFactoryRef = element.getAttribute("db-factory-ref");
|
||||
|
||||
BeanDefinitionBuilder mongoTemplateBuilder = BeanDefinitionBuilder.genericBeanDefinition(MongoTemplate.class);
|
||||
setPropertyValue(mongoTemplateBuilder, element, "write-concern", "writeConcern");
|
||||
|
||||
if (StringUtils.hasText(dbFactoryRef)) {
|
||||
mongoTemplateBuilder.addConstructorArgReference(dbFactoryRef);
|
||||
} else {
|
||||
mongoTemplateBuilder.addConstructorArgReference(BeanNames.DB_FACTORY);
|
||||
}
|
||||
|
||||
if (StringUtils.hasText(converterRef)) {
|
||||
mongoTemplateBuilder.addConstructorArgReference(converterRef);
|
||||
}
|
||||
|
||||
BeanDefinitionBuilder writeConcernPropertyEditorBuilder = getWriteConcernPropertyEditorBuilder();
|
||||
|
||||
BeanComponentDefinition component = helper.getComponent(writeConcernPropertyEditorBuilder);
|
||||
parserContext.registerBeanComponent(component);
|
||||
|
||||
return (AbstractBeanDefinition) helper.getComponentIdButFallback(mongoTemplateBuilder, BeanNames.MONGO_TEMPLATE)
|
||||
.getBeanDefinition();
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2010-2013 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.
|
||||
@@ -117,7 +117,6 @@ public class MongoFactoryBean implements FactoryBean<Mongo>, InitializingBean, D
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.beans.factory.InitializingBean#afterPropertiesSet()
|
||||
*/
|
||||
@SuppressWarnings("deprecation")
|
||||
public void afterPropertiesSet() throws Exception {
|
||||
|
||||
Mongo mongo;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2010-2013 the original author or authors.
|
||||
* Copyright 2010-2011 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.
|
||||
@@ -408,16 +408,11 @@ public interface MongoOperations {
|
||||
* specification
|
||||
* @param entityClass the parameterized type of the returned list.
|
||||
* @param collectionName name of the collection to retrieve the objects from
|
||||
*
|
||||
* @return the converted object
|
||||
*/
|
||||
<T> T findOne(Query query, Class<T> entityClass, String collectionName);
|
||||
|
||||
boolean exists(Query query, String collectionName);
|
||||
|
||||
boolean exists(Query query, Class<?> entityClass);
|
||||
|
||||
boolean exists(Query query, Class<?> entityClass, String collectionName);
|
||||
|
||||
/**
|
||||
* Map the results of an ad-hoc query on the collection for the entity class to a List of the specified type.
|
||||
* <p/>
|
||||
@@ -447,6 +442,7 @@ public interface MongoOperations {
|
||||
* specification
|
||||
* @param entityClass the parameterized type of the returned list.
|
||||
* @param collectionName name of the collection to retrieve the objects from
|
||||
*
|
||||
* @return the List of converted objects
|
||||
*/
|
||||
<T> List<T> find(Query query, Class<T> entityClass, String collectionName);
|
||||
@@ -468,6 +464,7 @@ public interface MongoOperations {
|
||||
* @param id the id of the document to return
|
||||
* @param entityClass the type to convert the document to
|
||||
* @param collectionName the collection to query for the document
|
||||
*
|
||||
* @param <T>
|
||||
* @return
|
||||
*/
|
||||
@@ -513,6 +510,7 @@ public interface MongoOperations {
|
||||
* specification
|
||||
* @param entityClass the parameterized type of the returned list.
|
||||
* @param collectionName name of the collection to retrieve the objects from
|
||||
*
|
||||
* @return the converted object
|
||||
*/
|
||||
<T> T findAndRemove(Query query, Class<T> entityClass, String collectionName);
|
||||
@@ -715,12 +713,11 @@ public interface MongoOperations {
|
||||
* Remove all documents that match the provided query document criteria from the the collection used to store the
|
||||
* entityClass. The Class parameter is also used to help convert the Id of the object if it is present in the query.
|
||||
*
|
||||
* @param <T>
|
||||
* @param query
|
||||
* @param entityClass
|
||||
*/
|
||||
void remove(Query query, Class<?> entityClass);
|
||||
|
||||
void remove(Query query, Class<?> entityClass, String collectionName);
|
||||
<T> void remove(Query query, Class<T> entityClass);
|
||||
|
||||
/**
|
||||
* Remove all documents from the specified collection that match the provided query document criteria. There is no
|
||||
@@ -737,4 +734,4 @@ public interface MongoOperations {
|
||||
* @return
|
||||
*/
|
||||
MongoConverter getConverter();
|
||||
}
|
||||
}
|
||||
@@ -52,6 +52,7 @@ import org.springframework.data.mapping.PersistentEntity;
|
||||
import org.springframework.data.mapping.context.MappingContext;
|
||||
import org.springframework.data.mapping.model.BeanWrapper;
|
||||
import org.springframework.data.mapping.model.MappingException;
|
||||
import org.springframework.data.mongodb.MongoDataIntegrityViolationException;
|
||||
import org.springframework.data.mongodb.MongoDbFactory;
|
||||
import org.springframework.data.mongodb.core.convert.MappingMongoConverter;
|
||||
import org.springframework.data.mongodb.core.convert.MongoConverter;
|
||||
@@ -68,11 +69,9 @@ import org.springframework.data.mongodb.core.mapping.MongoPersistentEntity;
|
||||
import org.springframework.data.mongodb.core.mapping.MongoPersistentProperty;
|
||||
import org.springframework.data.mongodb.core.mapping.MongoSimpleTypes;
|
||||
import org.springframework.data.mongodb.core.mapping.event.AfterConvertEvent;
|
||||
import org.springframework.data.mongodb.core.mapping.event.AfterDeleteEvent;
|
||||
import org.springframework.data.mongodb.core.mapping.event.AfterLoadEvent;
|
||||
import org.springframework.data.mongodb.core.mapping.event.AfterSaveEvent;
|
||||
import org.springframework.data.mongodb.core.mapping.event.BeforeConvertEvent;
|
||||
import org.springframework.data.mongodb.core.mapping.event.BeforeDeleteEvent;
|
||||
import org.springframework.data.mongodb.core.mapping.event.BeforeSaveEvent;
|
||||
import org.springframework.data.mongodb.core.mapping.event.MongoMappingEvent;
|
||||
import org.springframework.data.mongodb.core.mapreduce.GroupBy;
|
||||
@@ -481,24 +480,6 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware {
|
||||
}
|
||||
}
|
||||
|
||||
public boolean exists(Query query, Class<?> entityClass) {
|
||||
return exists(query, entityClass, determineCollectionName(entityClass));
|
||||
}
|
||||
|
||||
public boolean exists(Query query, String collectionName) {
|
||||
return exists(query, null, collectionName);
|
||||
}
|
||||
|
||||
public boolean exists(Query query, Class<?> entityClass, String collectionName) {
|
||||
|
||||
if (query == null) {
|
||||
throw new InvalidDataAccessApiUsageException("Query passed in to exist can't be null");
|
||||
}
|
||||
|
||||
DBObject mappedQuery = mapper.getMappedObject(query.getQueryObject(), getPersistentEntity(entityClass));
|
||||
return execute(collectionName, new FindCallback(mappedQuery)).hasNext();
|
||||
}
|
||||
|
||||
// Find methods that take a Query to express the query and that return a List of objects.
|
||||
|
||||
public <T> List<T> find(Query query, Class<T> entityClass) {
|
||||
@@ -816,6 +797,7 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware {
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
protected <T> void doSave(String collectionName, T objectToSave, MongoWriter<T> writer) {
|
||||
|
||||
assertUpdateableIdIfNotSet(objectToSave);
|
||||
@@ -828,7 +810,7 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware {
|
||||
writer.write(objectToSave, dbDoc);
|
||||
} else {
|
||||
try {
|
||||
dbDoc = (DBObject) JSON.parse((String) objectToSave);
|
||||
objectToSave = (T) JSON.parse((String) objectToSave);
|
||||
} catch (JSONParseException e) {
|
||||
throw new MappingException("Could not parse given String to save into a JSON document!", e);
|
||||
}
|
||||
@@ -1033,34 +1015,23 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware {
|
||||
}
|
||||
}
|
||||
|
||||
public void remove(Query query, String collectionName) {
|
||||
remove(query, null, collectionName);
|
||||
}
|
||||
|
||||
public void remove(Query query, Class<?> entityClass) {
|
||||
remove(query, entityClass, determineCollectionName(entityClass));
|
||||
}
|
||||
|
||||
public void remove(Query query, Class<?> entityClass, String collectionName) {
|
||||
doRemove(collectionName, query, entityClass);
|
||||
public <T> void remove(Query query, Class<T> entityClass) {
|
||||
Assert.notNull(query);
|
||||
doRemove(determineCollectionName(entityClass), query, entityClass);
|
||||
}
|
||||
|
||||
protected <T> void doRemove(final String collectionName, final Query query, final Class<T> entityClass) {
|
||||
|
||||
if (query == null) {
|
||||
throw new InvalidDataAccessApiUsageException("Query passed in to remove can't be null!");
|
||||
throw new InvalidDataAccessApiUsageException("Query passed in to remove can't be null");
|
||||
}
|
||||
|
||||
Assert.hasText(collectionName, "Collection name must not be null or empty!");
|
||||
|
||||
final DBObject queryObject = query.getQueryObject();
|
||||
final MongoPersistentEntity<?> entity = getPersistentEntity(entityClass);
|
||||
|
||||
execute(collectionName, new CollectionCallback<Void>() {
|
||||
public Void doInCollection(DBCollection collection) throws MongoException, DataAccessException {
|
||||
|
||||
maybeEmitEvent(new BeforeDeleteEvent<T>(queryObject, entityClass));
|
||||
|
||||
DBObject dboq = mapper.getMappedObject(queryObject, entity);
|
||||
|
||||
MongoAction mongoAction = new MongoAction(writeConcern, MongoActionOperation.REMOVE, collectionName,
|
||||
@@ -1074,14 +1045,15 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware {
|
||||
WriteResult wr = writeConcernToUse == null ? collection.remove(dboq) : collection.remove(dboq,
|
||||
writeConcernToUse);
|
||||
handleAnyWriteResultErrors(wr, dboq, MongoActionOperation.REMOVE);
|
||||
|
||||
maybeEmitEvent(new AfterDeleteEvent<T>(queryObject, entityClass));
|
||||
|
||||
return null;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void remove(final Query query, String collectionName) {
|
||||
doRemove(collectionName, query, null);
|
||||
}
|
||||
|
||||
public <T> List<T> findAll(Class<T> entityClass) {
|
||||
return executeFindMultiInternal(new FindCallback(null), null, new ReadDbObjectCallback<T>(mongoConverter,
|
||||
entityClass), determineCollectionName(entityClass));
|
||||
|
||||
@@ -17,11 +17,9 @@ package org.springframework.data.mongodb.core.convert;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
@@ -65,7 +63,6 @@ public class CustomConversions {
|
||||
private final Set<ConvertiblePair> writingPairs;
|
||||
private final Set<Class<?>> customSimpleTypes;
|
||||
private final SimpleTypeHolder simpleTypeHolder;
|
||||
private final Map<Class<?>, HashMap<Class<?>, CacheValue>> cache;
|
||||
|
||||
private final List<Object> converters;
|
||||
|
||||
@@ -88,7 +85,6 @@ public class CustomConversions {
|
||||
this.readingPairs = new HashSet<ConvertiblePair>();
|
||||
this.writingPairs = new HashSet<ConvertiblePair>();
|
||||
this.customSimpleTypes = new HashSet<Class<?>>();
|
||||
this.cache = new HashMap<Class<?>, HashMap<Class<?>, CacheValue>>();
|
||||
|
||||
this.converters = new ArrayList<Object>();
|
||||
this.converters.add(CustomToStringConverter.INSTANCE);
|
||||
@@ -272,11 +268,9 @@ public class CustomConversions {
|
||||
* @return
|
||||
*/
|
||||
public boolean hasCustomReadTarget(Class<?> source, Class<?> expectedTargetType) {
|
||||
|
||||
Assert.notNull(source);
|
||||
Assert.notNull(expectedTargetType);
|
||||
|
||||
return getCustomReadTarget(source, expectedTargetType) != null;
|
||||
return getCustomTarget(source, expectedTargetType, readingPairs) != null;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -305,32 +299,8 @@ public class CustomConversions {
|
||||
return null;
|
||||
}
|
||||
|
||||
private Class<?> getCustomReadTarget(Class<?> source, Class<?> expectedTargetType) {
|
||||
|
||||
Class<?> type = expectedTargetType == null ? PlaceholderType.class : expectedTargetType;
|
||||
|
||||
Map<Class<?>, CacheValue> map;
|
||||
CacheValue toReturn;
|
||||
|
||||
if ((map = cache.get(source)) == null || (toReturn = map.get(type)) == null) {
|
||||
|
||||
Class<?> target = getCustomTarget(source, type, readingPairs);
|
||||
|
||||
if (cache.get(source) == null) {
|
||||
cache.put(source, new HashMap<Class<?>, CacheValue>());
|
||||
}
|
||||
|
||||
Map<Class<?>, CacheValue> value = cache.get(source);
|
||||
toReturn = target == null ? CacheValue.NULL : new CacheValue(target);
|
||||
value.put(type, toReturn);
|
||||
}
|
||||
|
||||
return toReturn.clazz;
|
||||
}
|
||||
|
||||
@WritingConverter
|
||||
private enum CustomToStringConverter implements GenericConverter {
|
||||
|
||||
INSTANCE;
|
||||
|
||||
public Set<ConvertiblePair> getConvertibleTypes() {
|
||||
@@ -343,30 +313,4 @@ public class CustomConversions {
|
||||
return source.toString();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Placeholder type to allow registering not-found values in the converter cache.
|
||||
*
|
||||
* @author Patryk Wasik
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
private static class PlaceholderType {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Wrapper to safely store {@literal null} values in the type cache.
|
||||
*
|
||||
* @author Patryk Wasik
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
private static class CacheValue {
|
||||
|
||||
public static final CacheValue NULL = new CacheValue(null);
|
||||
private final Class<?> clazz;
|
||||
|
||||
public CacheValue(Class<?> clazz) {
|
||||
this.clazz = clazz;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -71,7 +71,6 @@ import com.mongodb.DBRef;
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
* @author Jon Brisbin
|
||||
* @author Patrik Wasik
|
||||
*/
|
||||
public class MappingMongoConverter extends AbstractMongoConverter implements ApplicationContextAware {
|
||||
|
||||
@@ -239,7 +238,10 @@ public class MappingMongoConverter extends AbstractMongoConverter implements App
|
||||
entity.doWithProperties(new PropertyHandler<MongoPersistentProperty>() {
|
||||
public void doWithPersistentProperty(MongoPersistentProperty prop) {
|
||||
|
||||
if (!dbo.containsField(prop.getFieldName()) || entity.isConstructorArgument(prop)) {
|
||||
boolean isConstructorProperty = entity.isConstructorArgument(prop);
|
||||
boolean hasValueForProperty = dbo.containsField(prop.getFieldName());
|
||||
|
||||
if (!hasValueForProperty || isConstructorProperty) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -412,7 +414,8 @@ public class MappingMongoConverter extends AbstractMongoConverter implements App
|
||||
}
|
||||
|
||||
if (valueType.isMap()) {
|
||||
DBObject mapDbObj = createMap((Map<Object, Object>) obj, prop);
|
||||
BasicDBObject mapDbObj = new BasicDBObject();
|
||||
writeMapInternal((Map<Object, Object>) obj, mapDbObj, type);
|
||||
dbo.put(name, mapDbObj);
|
||||
return;
|
||||
}
|
||||
@@ -492,42 +495,6 @@ public class MappingMongoConverter extends AbstractMongoConverter implements App
|
||||
return dbList;
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes the given {@link Map} using the given {@link MongoPersistentProperty} information.
|
||||
*
|
||||
* @param map must not {@literal null}.
|
||||
* @param property must not be {@literal null}.
|
||||
* @return
|
||||
*/
|
||||
protected DBObject createMap(Map<Object, Object> map, MongoPersistentProperty property) {
|
||||
|
||||
Assert.notNull(map, "Given map must not be null!");
|
||||
Assert.notNull(property, "PersistentProperty must not be null!");
|
||||
|
||||
if (!property.isDbReference()) {
|
||||
return writeMapInternal(map, new BasicDBObject(), property.getTypeInformation());
|
||||
}
|
||||
|
||||
BasicDBObject dbObject = new BasicDBObject();
|
||||
|
||||
for (Map.Entry<Object, Object> entry : map.entrySet()) {
|
||||
|
||||
Object key = entry.getKey();
|
||||
Object value = entry.getValue();
|
||||
|
||||
if (conversions.isSimpleType(key.getClass())) {
|
||||
|
||||
String simpleKey = potentiallyEscapeMapKey(key.toString());
|
||||
dbObject.put(simpleKey, value != null ? createDBRef(value, property.getDBRef()) : null);
|
||||
|
||||
} else {
|
||||
throw new MappingException("Cannot use a complex object as a key value.");
|
||||
}
|
||||
}
|
||||
|
||||
return dbObject;
|
||||
}
|
||||
|
||||
/**
|
||||
* Populates the given {@link BasicDBList} with values from the given {@link Collection}.
|
||||
*
|
||||
|
||||
@@ -41,7 +41,6 @@ import com.mongodb.DBRef;
|
||||
*
|
||||
* @author Jon Brisbin
|
||||
* @author Oliver Gierke
|
||||
* @author Patryk Wasik
|
||||
*/
|
||||
public class QueryMapper {
|
||||
|
||||
@@ -84,8 +83,11 @@ public class QueryMapper {
|
||||
|
||||
for (String key : query.keySet()) {
|
||||
|
||||
Field field = entity == null ? new Field(key) : new MetadataBackedField(key, entity, mappingContext);
|
||||
result.put(field.getMappedKey(), getMappedValue(query.get(key), field));
|
||||
MongoPersistentProperty targetProperty = getTargetProperty(key, entity);
|
||||
String newKey = determineKey(key, entity);
|
||||
Object value = query.get(key);
|
||||
|
||||
result.put(newKey, getMappedValue(value, targetProperty, newKey));
|
||||
}
|
||||
|
||||
return result;
|
||||
@@ -123,13 +125,13 @@ public class QueryMapper {
|
||||
* @param property
|
||||
* @return
|
||||
*/
|
||||
public DBObject getMappedKeyword(Keyword keyword, Field property) {
|
||||
public DBObject getMappedKeyword(Keyword keyword, MongoPersistentProperty property) {
|
||||
|
||||
if (property.isAssociation()) {
|
||||
convertAssociation(keyword.value, property.getProperty());
|
||||
convertAssociation(keyword.value, property);
|
||||
}
|
||||
|
||||
return new BasicDBObject(keyword.key, getMappedValue(keyword.value, property.with(keyword.key)));
|
||||
return new BasicDBObject(keyword.key, getMappedValue(keyword.value, property, keyword.key));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -141,9 +143,13 @@ public class QueryMapper {
|
||||
* @param newKey the key the value will be bound to eventually
|
||||
* @return
|
||||
*/
|
||||
private Object getMappedValue(Object source, Field key) {
|
||||
private Object getMappedValue(Object source, MongoPersistentProperty property, String newKey) {
|
||||
|
||||
if (key.isIdField()) {
|
||||
if (property == null) {
|
||||
return convertSimpleOrDBObject(source, null);
|
||||
}
|
||||
|
||||
if (property.isIdProperty() || "_id".equals(newKey)) {
|
||||
|
||||
if (source instanceof DBObject) {
|
||||
DBObject valueDbo = (DBObject) source;
|
||||
@@ -167,12 +173,57 @@ public class QueryMapper {
|
||||
}
|
||||
}
|
||||
|
||||
if (key.isAssociation()) {
|
||||
return Keyword.isKeyword(source) ? getMappedKeyword(new Keyword(source), key) : convertAssociation(source,
|
||||
key.getProperty());
|
||||
if (property.isAssociation()) {
|
||||
return Keyword.isKeyword(source) ? getMappedKeyword(new Keyword(source), property) : convertAssociation(source,
|
||||
property);
|
||||
}
|
||||
|
||||
return convertSimpleOrDBObject(source, key.getPropertyEntity());
|
||||
return convertSimpleOrDBObject(source, mappingContext.getPersistentEntity(property));
|
||||
}
|
||||
|
||||
private MongoPersistentProperty getTargetProperty(String key, MongoPersistentEntity<?> entity) {
|
||||
|
||||
if (isIdKey(key, entity)) {
|
||||
return entity.getIdProperty();
|
||||
}
|
||||
|
||||
PersistentPropertyPath<MongoPersistentProperty> path = getPath(key, entity);
|
||||
return path == null ? null : path.getLeafProperty();
|
||||
}
|
||||
|
||||
private PersistentPropertyPath<MongoPersistentProperty> getPath(String key, MongoPersistentEntity<?> entity) {
|
||||
|
||||
if (entity == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
try {
|
||||
PropertyPath path = PropertyPath.from(key, entity.getTypeInformation());
|
||||
return mappingContext.getPersistentPropertyPath(path);
|
||||
} catch (PropertyReferenceException e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the translated key assuming the given one is a propert (path) reference.
|
||||
*
|
||||
* @param key the source key
|
||||
* @param entity the base entity
|
||||
* @return the translated key
|
||||
*/
|
||||
private String determineKey(String key, MongoPersistentEntity<?> entity) {
|
||||
|
||||
if (entity == null) {
|
||||
return key;
|
||||
}
|
||||
|
||||
if (!entity.hasIdProperty() && DEFAULT_ID_NAMES.contains(key)) {
|
||||
return "_id";
|
||||
}
|
||||
|
||||
PersistentPropertyPath<MongoPersistentProperty> path = getPath(key, entity);
|
||||
return path == null ? key : path.toDotPath(MongoPersistentProperty.PropertyToFieldNameConverter.INSTANCE);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -216,17 +267,29 @@ public class QueryMapper {
|
||||
return result;
|
||||
}
|
||||
|
||||
if (property.isMap()) {
|
||||
BasicDBObject result = new BasicDBObject();
|
||||
DBObject dbObject = (DBObject) source;
|
||||
for (String key : dbObject.keySet()) {
|
||||
Object o = dbObject.get(key);
|
||||
result.put(key, o instanceof DBRef ? o : converter.toDBRef(o, property));
|
||||
}
|
||||
return result;
|
||||
return source == null || source instanceof DBRef ? source : converter.toDBRef(source, property);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether the given key will be considered an id key.
|
||||
*
|
||||
* @param key
|
||||
* @param entity
|
||||
* @return
|
||||
*/
|
||||
private boolean isIdKey(String key, MongoPersistentEntity<?> entity) {
|
||||
|
||||
if (entity == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return source == null || source instanceof DBRef ? source : converter.toDBRef(source, property);
|
||||
MongoPersistentProperty idProperty = entity.getIdProperty();
|
||||
|
||||
if (idProperty != null) {
|
||||
return idProperty.getName().equals(key) || idProperty.getFieldName().equals(key);
|
||||
}
|
||||
|
||||
return DEFAULT_ID_NAMES.contains(key);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -285,192 +348,4 @@ public class QueryMapper {
|
||||
return dbObject.keySet().size() == 1 && dbObject.keySet().iterator().next().startsWith("$");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Value object to represent a field and its meta-information.
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
private static class Field {
|
||||
|
||||
private static final String ID_KEY = "_id";
|
||||
|
||||
protected final String name;
|
||||
|
||||
/**
|
||||
* Creates a new {@link Field} without meta-information but the given name.
|
||||
*
|
||||
* @param name must not be {@literal null} or empty.
|
||||
*/
|
||||
public Field(String name) {
|
||||
|
||||
Assert.hasText(name, "Name must not be null!");
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a new {@link Field} with the given name.
|
||||
*
|
||||
* @param name must not be {@literal null} or empty.
|
||||
* @return
|
||||
*/
|
||||
public Field with(String name) {
|
||||
return new Field(name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether the current field is the id field.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public boolean isIdField() {
|
||||
return ID_KEY.equals(name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the underlying {@link MongoPersistentProperty} backing the field.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public MongoPersistentProperty getProperty() {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the {@link MongoPersistentEntity} that field is conatined in.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public MongoPersistentEntity<?> getPropertyEntity() {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether the field represents an association.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public boolean isAssociation() {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the key to be used in the mapped document eventually.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public String getMappedKey() {
|
||||
return isIdField() ? ID_KEY : name;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Extension of {@link Field} to be backed with mapping metadata.
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
private static class MetadataBackedField extends Field {
|
||||
|
||||
private final MongoPersistentEntity<?> entity;
|
||||
private final MappingContext<? extends MongoPersistentEntity<?>, MongoPersistentProperty> mappingContext;
|
||||
private final MongoPersistentProperty property;
|
||||
|
||||
/**
|
||||
* Creates a new {@link MetadataBackedField} with the given name, {@link MongoPersistentEntity} and
|
||||
* {@link MappingContext}.
|
||||
*
|
||||
* @param name must not be {@literal null} or empty.
|
||||
* @param entity must not be {@literal null}.
|
||||
* @param context must not be {@literal null}.
|
||||
*/
|
||||
public MetadataBackedField(String name, MongoPersistentEntity<?> entity,
|
||||
MappingContext<? extends MongoPersistentEntity<?>, MongoPersistentProperty> context) {
|
||||
|
||||
super(name);
|
||||
|
||||
Assert.notNull(entity, "MongoPersistentEntity must not be null!");
|
||||
|
||||
this.entity = entity;
|
||||
this.mappingContext = context;
|
||||
|
||||
PersistentPropertyPath<MongoPersistentProperty> path = getPath(name);
|
||||
this.property = path == null ? null : path.getLeafProperty();
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.mongodb.core.convert.QueryMapper.Field#with(java.lang.String)
|
||||
*/
|
||||
@Override
|
||||
public MetadataBackedField with(String name) {
|
||||
return new MetadataBackedField(name, entity, mappingContext);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.mongodb.core.convert.QueryMapper.Field#isIdKey()
|
||||
*/
|
||||
@Override
|
||||
public boolean isIdField() {
|
||||
|
||||
MongoPersistentProperty idProperty = entity.getIdProperty();
|
||||
|
||||
if (idProperty != null) {
|
||||
return idProperty.getName().equals(name) || idProperty.getFieldName().equals(name);
|
||||
}
|
||||
|
||||
return DEFAULT_ID_NAMES.contains(name);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.mongodb.core.convert.QueryMapper.Field#getProperty()
|
||||
*/
|
||||
@Override
|
||||
public MongoPersistentProperty getProperty() {
|
||||
return property;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.mongodb.core.convert.QueryMapper.Field#getEntity()
|
||||
*/
|
||||
@Override
|
||||
public MongoPersistentEntity<?> getPropertyEntity() {
|
||||
MongoPersistentProperty property = getProperty();
|
||||
return property == null ? null : mappingContext.getPersistentEntity(property);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.mongodb.core.convert.QueryMapper.Field#isAssociation()
|
||||
*/
|
||||
@Override
|
||||
public boolean isAssociation() {
|
||||
|
||||
MongoPersistentProperty property = getProperty();
|
||||
return property == null ? false : property.isAssociation();
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.mongodb.core.convert.QueryMapper.Field#getTargetKey()
|
||||
*/
|
||||
@Override
|
||||
public String getMappedKey() {
|
||||
|
||||
PersistentPropertyPath<MongoPersistentProperty> path = getPath(name);
|
||||
return path == null ? name : path.toDotPath(MongoPersistentProperty.PropertyToFieldNameConverter.INSTANCE);
|
||||
}
|
||||
|
||||
private PersistentPropertyPath<MongoPersistentProperty> getPath(String name) {
|
||||
|
||||
try {
|
||||
PropertyPath path = PropertyPath.from(name, entity.getTypeInformation());
|
||||
return mappingContext.getPersistentPropertyPath(path);
|
||||
} catch (PropertyReferenceException e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2011-2013 the original author or authors.
|
||||
* Copyright 2011-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.
|
||||
@@ -26,7 +26,6 @@ import java.lang.annotation.Target;
|
||||
*
|
||||
* @author Jon Brisbin
|
||||
* @author Oliver Gierke
|
||||
* @author Philipp Schneider
|
||||
*/
|
||||
@Target({ ElementType.TYPE })
|
||||
@Documented
|
||||
@@ -70,12 +69,4 @@ public @interface CompoundIndex {
|
||||
* @return
|
||||
*/
|
||||
String collection() default "";
|
||||
|
||||
/**
|
||||
* If {@literal true} the index will be created in the background.
|
||||
*
|
||||
* @see http://docs.mongodb.org/manual/core/indexes/#background-construction
|
||||
* @return
|
||||
*/
|
||||
boolean background() default false;
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2010-2013 the original author or authors.
|
||||
* Copyright 2010-2011 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.
|
||||
@@ -18,20 +18,18 @@ package org.springframework.data.mongodb.core.index;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.springframework.data.domain.Sort.Direction;
|
||||
import org.springframework.data.mongodb.core.query.Order;
|
||||
|
||||
import com.mongodb.BasicDBObject;
|
||||
import com.mongodb.DBObject;
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
public class Index implements IndexDefinition {
|
||||
|
||||
public enum Duplicates {
|
||||
RETAIN, DROP
|
||||
}
|
||||
|
||||
private final Map<String, Direction> fieldSpec = new LinkedHashMap<String, Direction>();
|
||||
private final Map<String, Order> fieldSpec = new LinkedHashMap<String, Order>();
|
||||
|
||||
private String name;
|
||||
|
||||
@@ -44,37 +42,12 @@ public class Index implements IndexDefinition {
|
||||
public Index() {
|
||||
}
|
||||
|
||||
public Index(String key, Direction direction) {
|
||||
fieldSpec.put(key, direction);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new {@link Indexed} on the given key and {@link Order}.
|
||||
*
|
||||
* @deprecated use {@link #Index(String, Direction)} instead.
|
||||
* @param key must not be {@literal null} or empty.
|
||||
* @param order must not be {@literal null}.
|
||||
*/
|
||||
@Deprecated
|
||||
public Index(String key, Order order) {
|
||||
this(key, order.toDirection());
|
||||
fieldSpec.put(key, order);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds the given field to the index.
|
||||
*
|
||||
* @deprecated use {@link #on(String, Direction)} instead.
|
||||
* @param key must not be {@literal null} or empty.
|
||||
* @param order must not be {@literal null}.
|
||||
* @return
|
||||
*/
|
||||
@Deprecated
|
||||
public Index on(String key, Order order) {
|
||||
return on(key, order.toDirection());
|
||||
}
|
||||
|
||||
public Index on(String key, Direction direction) {
|
||||
fieldSpec.put(key, direction);
|
||||
fieldSpec.put(key, order);
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -103,7 +76,7 @@ public class Index implements IndexDefinition {
|
||||
public DBObject getIndexKeys() {
|
||||
DBObject dbo = new BasicDBObject();
|
||||
for (String k : fieldSpec.keySet()) {
|
||||
dbo.put(k, fieldSpec.get(k).equals(Direction.ASC) ? 1 : -1);
|
||||
dbo.put(k, (fieldSpec.get(k).equals(Order.ASCENDING) ? 1 : -1));
|
||||
}
|
||||
return dbo;
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2013 the original author or authors.
|
||||
* 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.
|
||||
@@ -15,7 +15,6 @@
|
||||
*/
|
||||
package org.springframework.data.mongodb.core.index;
|
||||
|
||||
import org.springframework.data.domain.Sort.Direction;
|
||||
import org.springframework.data.mongodb.core.query.Order;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.ObjectUtils;
|
||||
@@ -25,38 +24,30 @@ import org.springframework.util.ObjectUtils;
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
@SuppressWarnings("deprecation")
|
||||
public final class IndexField {
|
||||
|
||||
private final String key;
|
||||
private final Direction direction;
|
||||
private final Order order;
|
||||
private final boolean isGeo;
|
||||
|
||||
private IndexField(String key, Direction direction, boolean isGeo) {
|
||||
private IndexField(String key, Order order, boolean isGeo) {
|
||||
|
||||
Assert.hasText(key);
|
||||
Assert.isTrue(direction != null ^ isGeo);
|
||||
Assert.isTrue(order != null ^ isGeo);
|
||||
|
||||
this.key = key;
|
||||
this.direction = direction;
|
||||
this.order = order;
|
||||
this.isGeo = isGeo;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a default {@link IndexField} with the given key and {@link Order}.
|
||||
*
|
||||
* @deprecated use {@link #create(String, Direction)}.
|
||||
* @param key must not be {@literal null} or emtpy.
|
||||
* @param direction must not be {@literal null}.
|
||||
* @param order must not be {@literal null}.
|
||||
* @return
|
||||
*/
|
||||
@Deprecated
|
||||
public static IndexField create(String key, Order order) {
|
||||
Assert.notNull(order);
|
||||
return new IndexField(key, order.toDirection(), false);
|
||||
}
|
||||
|
||||
public static IndexField create(String key, Direction order) {
|
||||
Assert.notNull(order);
|
||||
return new IndexField(key, order, false);
|
||||
}
|
||||
@@ -79,23 +70,12 @@ public final class IndexField {
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the direction of the {@link IndexField} or {@literal null} in case we have a geo index field.
|
||||
* Returns the order of the {@link IndexField} or {@literal null} in case we have a geo index field.
|
||||
*
|
||||
* @deprecated use {@link #getDirection()} instead.
|
||||
* @return the direction
|
||||
* @return the order
|
||||
*/
|
||||
@Deprecated
|
||||
public Order getOrder() {
|
||||
return Direction.ASC.equals(direction) ? Order.ASCENDING : Order.DESCENDING;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the direction of the {@link IndexField} or {@literal null} in case we have a geo index field.
|
||||
*
|
||||
* @return the direction
|
||||
*/
|
||||
public Direction getDirection() {
|
||||
return direction;
|
||||
return order;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -124,8 +104,7 @@ public final class IndexField {
|
||||
|
||||
IndexField that = (IndexField) obj;
|
||||
|
||||
return this.key.equals(that.key) && ObjectUtils.nullSafeEquals(this.direction, that.direction)
|
||||
&& this.isGeo == that.isGeo;
|
||||
return this.key.equals(that.key) && ObjectUtils.nullSafeEquals(this.order, that.order) && this.isGeo == that.isGeo;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -137,7 +116,7 @@ public final class IndexField {
|
||||
|
||||
int result = 17;
|
||||
result += 31 * ObjectUtils.nullSafeHashCode(key);
|
||||
result += 31 * ObjectUtils.nullSafeHashCode(direction);
|
||||
result += 31 * ObjectUtils.nullSafeHashCode(order);
|
||||
result += 31 * ObjectUtils.nullSafeHashCode(isGeo);
|
||||
return result;
|
||||
}
|
||||
@@ -148,6 +127,6 @@ public final class IndexField {
|
||||
*/
|
||||
@Override
|
||||
public String toString() {
|
||||
return String.format("IndexField [ key: %s, direction: %s, isGeo: %s]", key, direction, isGeo);
|
||||
return String.format("IndexField [ key: %s, order: %s, isGeo: %s]", key, order, isGeo);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
/*
|
||||
* Copyright 2011-2013 the original author or authors.
|
||||
* Copyright (c) 2011 by the original author(s).
|
||||
*
|
||||
* 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,
|
||||
@@ -13,6 +13,7 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.data.mongodb.core.index;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
@@ -23,9 +24,7 @@ import java.lang.annotation.Target;
|
||||
/**
|
||||
* Mark a field to be indexed using MongoDB's indexing feature.
|
||||
*
|
||||
* @author Jon Brisbin
|
||||
* @author Oliver Gierke
|
||||
* @author Philipp Schneider
|
||||
* @author Jon Brisbin <jbrisbin@vmware.com>
|
||||
*/
|
||||
@Target(ElementType.FIELD)
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@@ -42,12 +41,4 @@ public @interface Indexed {
|
||||
String name() default "";
|
||||
|
||||
String collection() default "";
|
||||
|
||||
/**
|
||||
* If {@literal true} the index will be created in the background.
|
||||
*
|
||||
* @see http://docs.mongodb.org/manual/core/indexes/#background-construction
|
||||
* @return
|
||||
*/
|
||||
boolean background() default false;
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2011-2013 the original author or authors.
|
||||
* Copyright 2011-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.
|
||||
@@ -43,7 +43,6 @@ import com.mongodb.util.JSON;
|
||||
*
|
||||
* @author Jon Brisbin
|
||||
* @author Oliver Gierke
|
||||
* @author Philipp Schneider
|
||||
*/
|
||||
public class MongoPersistentEntityIndexCreator implements
|
||||
ApplicationListener<MappingContextEvent<MongoPersistentEntity<?>, MongoPersistentProperty>> {
|
||||
@@ -107,8 +106,7 @@ public class MongoPersistentEntityIndexCreator implements
|
||||
String indexColl = StringUtils.hasText(index.collection()) ? index.collection() : entity.getCollection();
|
||||
DBObject definition = (DBObject) JSON.parse(index.def());
|
||||
|
||||
ensureIndex(indexColl, index.name(), definition, index.unique(), index.dropDups(), index.sparse(),
|
||||
index.background());
|
||||
ensureIndex(indexColl, index.name(), definition, index.unique(), index.dropDups(), index.sparse());
|
||||
|
||||
if (log.isDebugEnabled()) {
|
||||
log.debug("Created compound index " + index);
|
||||
@@ -142,8 +140,7 @@ public class MongoPersistentEntityIndexCreator implements
|
||||
int direction = index.direction() == IndexDirection.ASCENDING ? 1 : -1;
|
||||
DBObject definition = new BasicDBObject(persistentProperty.getFieldName(), direction);
|
||||
|
||||
ensureIndex(collection, name, definition, index.unique(), index.dropDups(), index.sparse(),
|
||||
index.background());
|
||||
ensureIndex(collection, name, definition, index.unique(), index.dropDups(), index.sparse());
|
||||
|
||||
if (log.isDebugEnabled()) {
|
||||
log.debug("Created property index " + index);
|
||||
@@ -194,14 +191,13 @@ public class MongoPersistentEntityIndexCreator implements
|
||||
* @param sparse sparse or not
|
||||
*/
|
||||
protected void ensureIndex(String collection, String name, DBObject indexDefinition, boolean unique,
|
||||
boolean dropDups, boolean sparse, boolean background) {
|
||||
boolean dropDups, boolean sparse) {
|
||||
|
||||
DBObject opts = new BasicDBObject();
|
||||
opts.put("name", name);
|
||||
opts.put("dropDups", dropDups);
|
||||
opts.put("sparse", sparse);
|
||||
opts.put("unique", unique);
|
||||
opts.put("background", background);
|
||||
|
||||
mongoDbFactory.getDb().getCollection(collection).ensureIndex(indexDefinition, opts);
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2011-2013 the original author or authors.
|
||||
* Copyright 2011-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.
|
||||
@@ -16,19 +16,13 @@
|
||||
package org.springframework.data.mongodb.core.mapping;
|
||||
|
||||
import java.util.Comparator;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.springframework.beans.BeansException;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.ApplicationContextAware;
|
||||
import org.springframework.context.expression.BeanFactoryAccessor;
|
||||
import org.springframework.context.expression.BeanFactoryResolver;
|
||||
import org.springframework.data.mapping.Association;
|
||||
import org.springframework.data.mapping.AssociationHandler;
|
||||
import org.springframework.data.mapping.PropertyHandler;
|
||||
import org.springframework.data.mapping.model.BasicPersistentEntity;
|
||||
import org.springframework.data.mapping.model.MappingException;
|
||||
import org.springframework.data.mongodb.MongoCollectionUtils;
|
||||
import org.springframework.data.util.TypeInformation;
|
||||
import org.springframework.expression.Expression;
|
||||
@@ -47,7 +41,6 @@ import org.springframework.util.StringUtils;
|
||||
public class BasicMongoPersistentEntity<T> extends BasicPersistentEntity<T, MongoPersistentProperty> implements
|
||||
MongoPersistentEntity<T>, ApplicationContextAware {
|
||||
|
||||
private static final String AMBIGUOUS_FIELD_MAPPING = "Ambiguous field mapping detected! Both %s and %s map to the same field name %s! Disambiguate using @Field annotation!";
|
||||
private final String collection;
|
||||
private final SpelExpressionParser parser;
|
||||
private final StandardEvaluationContext context;
|
||||
@@ -96,19 +89,6 @@ public class BasicMongoPersistentEntity<T> extends BasicPersistentEntity<T, Mong
|
||||
return expression.getValue(context, String.class);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.mapping.model.BasicPersistentEntity#verify()
|
||||
*/
|
||||
@Override
|
||||
public void verify() {
|
||||
|
||||
AssertFieldNameUniquenessHandler handler = new AssertFieldNameUniquenessHandler();
|
||||
|
||||
doWithProperties(handler);
|
||||
doWithAssociations(handler);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@link Comparator} implementation inspecting the {@link MongoPersistentProperty}'s order.
|
||||
*
|
||||
@@ -135,37 +115,4 @@ public class BasicMongoPersistentEntity<T> extends BasicPersistentEntity<T, Mong
|
||||
return o1.getFieldOrder() - o2.getFieldOrder();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Handler to collect {@link MongoPersistentProperty} instances and check that each of them is mapped to a distinct
|
||||
* field name.
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
private static class AssertFieldNameUniquenessHandler implements PropertyHandler<MongoPersistentProperty>,
|
||||
AssociationHandler<MongoPersistentProperty> {
|
||||
|
||||
private final Map<String, MongoPersistentProperty> properties = new HashMap<String, MongoPersistentProperty>();
|
||||
|
||||
public void doWithPersistentProperty(MongoPersistentProperty persistentProperty) {
|
||||
assertUniqueness(persistentProperty);
|
||||
}
|
||||
|
||||
public void doWithAssociation(Association<MongoPersistentProperty> association) {
|
||||
assertUniqueness(association.getInverse());
|
||||
}
|
||||
|
||||
private void assertUniqueness(MongoPersistentProperty property) {
|
||||
|
||||
String fieldName = property.getFieldName();
|
||||
MongoPersistentProperty existingProperty = properties.get(fieldName);
|
||||
|
||||
if (existingProperty != null) {
|
||||
throw new MappingException(String.format(AMBIGUOUS_FIELD_MAPPING, property.toString(),
|
||||
existingProperty.toString(), fieldName));
|
||||
}
|
||||
|
||||
properties.put(fieldName, property);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2011-2013 the original author or authors.
|
||||
* Copyright 2011-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.
|
||||
@@ -26,7 +26,6 @@ import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.data.mapping.Association;
|
||||
import org.springframework.data.mapping.model.AnnotationBasedPersistentProperty;
|
||||
import org.springframework.data.mapping.model.MappingException;
|
||||
import org.springframework.data.mapping.model.SimpleTypeHolder;
|
||||
import org.springframework.util.ReflectionUtils;
|
||||
import org.springframework.util.StringUtils;
|
||||
@@ -61,8 +60,6 @@ public class BasicMongoPersistentProperty extends AnnotationBasedPersistentPrope
|
||||
CAUSE_FIELD = ReflectionUtils.findField(Throwable.class, "cause");
|
||||
}
|
||||
|
||||
private final FieldNamingStrategy fieldNamingStrategy;
|
||||
|
||||
/**
|
||||
* Creates a new {@link BasicMongoPersistentProperty}.
|
||||
*
|
||||
@@ -70,14 +67,10 @@ public class BasicMongoPersistentProperty extends AnnotationBasedPersistentPrope
|
||||
* @param propertyDescriptor
|
||||
* @param owner
|
||||
* @param simpleTypeHolder
|
||||
* @param fieldNamingStrategy
|
||||
*/
|
||||
public BasicMongoPersistentProperty(Field field, PropertyDescriptor propertyDescriptor,
|
||||
MongoPersistentEntity<?> owner, SimpleTypeHolder simpleTypeHolder, FieldNamingStrategy fieldNamingStrategy) {
|
||||
|
||||
MongoPersistentEntity<?> owner, SimpleTypeHolder simpleTypeHolder) {
|
||||
super(field, propertyDescriptor, owner, simpleTypeHolder);
|
||||
this.fieldNamingStrategy = fieldNamingStrategy == null ? PropertyNameFieldNamingStrategy.INSTANCE
|
||||
: fieldNamingStrategy;
|
||||
|
||||
if (isIdProperty() && getFieldName() != ID_FIELD_NAME) {
|
||||
LOG.warn("Customizing field name for id property not allowed! Custom name will not be considered!");
|
||||
@@ -120,20 +113,9 @@ public class BasicMongoPersistentProperty extends AnnotationBasedPersistentPrope
|
||||
return ID_FIELD_NAME;
|
||||
}
|
||||
|
||||
org.springframework.data.mongodb.core.mapping.Field annotation = findAnnotation(org.springframework.data.mongodb.core.mapping.Field.class);
|
||||
|
||||
if (annotation != null && StringUtils.hasText(annotation.value())) {
|
||||
return annotation.value();
|
||||
}
|
||||
|
||||
String fieldName = fieldNamingStrategy.getFieldName(this);
|
||||
|
||||
if (!StringUtils.hasText(fieldName)) {
|
||||
throw new MappingException(String.format("Invalid (null or empty) field name returned for property %s by %s!",
|
||||
this, fieldNamingStrategy.getClass()));
|
||||
}
|
||||
|
||||
return fieldName;
|
||||
org.springframework.data.mongodb.core.mapping.Field annotation = getField().getAnnotation(
|
||||
org.springframework.data.mongodb.core.mapping.Field.class);
|
||||
return annotation != null && StringUtils.hasText(annotation.value()) ? annotation.value() : field.getName();
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2011-2013 the original author or authors.
|
||||
* Copyright 2011-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.
|
||||
@@ -38,11 +38,10 @@ public class CachingMongoPersistentProperty extends BasicMongoPersistentProperty
|
||||
* @param propertyDescriptor
|
||||
* @param owner
|
||||
* @param simpleTypeHolder
|
||||
* @param fieldNamingStrategy
|
||||
*/
|
||||
public CachingMongoPersistentProperty(Field field, PropertyDescriptor propertyDescriptor,
|
||||
MongoPersistentEntity<?> owner, SimpleTypeHolder simpleTypeHolder, FieldNamingStrategy fieldNamingStrategy) {
|
||||
super(field, propertyDescriptor, owner, simpleTypeHolder, fieldNamingStrategy);
|
||||
MongoPersistentEntity<?> owner, SimpleTypeHolder simpleTypeHolder) {
|
||||
super(field, propertyDescriptor, owner, simpleTypeHolder);
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -1,46 +0,0 @@
|
||||
/*
|
||||
* Copyright 2013 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.mapping;
|
||||
|
||||
import java.util.Locale;
|
||||
|
||||
/**
|
||||
* {@link FieldNamingStrategy} that abbreviates field names by using the very first letter of the camel case parts of
|
||||
* the {@link MongoPersistentProperty}'s name.
|
||||
*
|
||||
* @since 1.3
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
public class CamelCaseAbbreviatingFieldNamingStrategy implements FieldNamingStrategy {
|
||||
|
||||
private static final String CAMEL_CASE_PATTERN = "(?<!(^|[A-Z]))(?=[A-Z])|(?<!^)(?=[A-Z][a-z])";
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.mongodb.core.mapping.FieldNamingStrategy#getFieldName(org.springframework.data.mongodb.core.mapping.MongoPersistentProperty)
|
||||
*/
|
||||
public String getFieldName(MongoPersistentProperty property) {
|
||||
|
||||
String[] parts = property.getName().split(CAMEL_CASE_PATTERN);
|
||||
StringBuilder builder = new StringBuilder();
|
||||
|
||||
for (String part : parts) {
|
||||
builder.append(part.substring(0, 1).toLowerCase(Locale.US));
|
||||
}
|
||||
|
||||
return builder.toString();
|
||||
}
|
||||
}
|
||||
@@ -1,36 +0,0 @@
|
||||
/*
|
||||
* Copyright 2013 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.mapping;
|
||||
|
||||
/**
|
||||
* SPI interface to determine how to name document fields in cases the field name is not manually defined.
|
||||
*
|
||||
* @see Field
|
||||
* @see PropertyNameFieldNamingStrategy
|
||||
* @see CamelCaseAbbreviatingFieldNamingStrategy
|
||||
* @since 1.3
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
public interface FieldNamingStrategy {
|
||||
|
||||
/**
|
||||
* Returns the field name to be used for the given {@link MongoPersistentProperty}.
|
||||
*
|
||||
* @param property must not be {@literal null} or empty;
|
||||
* @return
|
||||
*/
|
||||
String getFieldName(MongoPersistentProperty property);
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2011-2013 the original author or authors.
|
||||
* Copyright 2011-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.
|
||||
@@ -37,9 +37,6 @@ import org.springframework.data.util.TypeInformation;
|
||||
public class MongoMappingContext extends AbstractMappingContext<BasicMongoPersistentEntity<?>, MongoPersistentProperty>
|
||||
implements ApplicationContextAware {
|
||||
|
||||
private static final FieldNamingStrategy DEFAULT_NAMING_STRATEGY = PropertyNameFieldNamingStrategy.INSTANCE;
|
||||
|
||||
private FieldNamingStrategy fieldNamingStrategy = DEFAULT_NAMING_STRATEGY;
|
||||
private ApplicationContext context;
|
||||
|
||||
/**
|
||||
@@ -49,17 +46,6 @@ public class MongoMappingContext extends AbstractMappingContext<BasicMongoPersis
|
||||
setSimpleTypeHolder(MongoSimpleTypes.HOLDER);
|
||||
}
|
||||
|
||||
/**
|
||||
* Configures the {@link FieldNamingStrategy} to be used to determine the field name if no manual mapping is applied.
|
||||
* Defaults to a strategy using the plain property name.
|
||||
*
|
||||
* @param fieldNamingStrategy the {@link FieldNamingStrategy} to be used to determine the field name if no manual
|
||||
* mapping is applied.
|
||||
*/
|
||||
public void setFieldNamingStrategy(FieldNamingStrategy fieldNamingStrategy) {
|
||||
this.fieldNamingStrategy = fieldNamingStrategy == null ? DEFAULT_NAMING_STRATEGY : fieldNamingStrategy;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.mapping.context.AbstractMappingContext#shouldCreatePersistentEntityFor(org.springframework.data.util.TypeInformation)
|
||||
@@ -76,7 +62,7 @@ public class MongoMappingContext extends AbstractMappingContext<BasicMongoPersis
|
||||
@Override
|
||||
public MongoPersistentProperty createPersistentProperty(Field field, PropertyDescriptor descriptor,
|
||||
BasicMongoPersistentEntity<?> owner, SimpleTypeHolder simpleTypeHolder) {
|
||||
return new CachingMongoPersistentProperty(field, descriptor, owner, simpleTypeHolder, fieldNamingStrategy);
|
||||
return new CachingMongoPersistentProperty(field, descriptor, owner, simpleTypeHolder);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -101,6 +87,8 @@ public class MongoMappingContext extends AbstractMappingContext<BasicMongoPersis
|
||||
*/
|
||||
@Override
|
||||
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
|
||||
|
||||
this.context = applicationContext;
|
||||
super.setApplicationContext(applicationContext);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,35 +0,0 @@
|
||||
/*
|
||||
* Copyright 2013 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.mapping;
|
||||
|
||||
/**
|
||||
* {@link FieldNamingStrategy} simply using the {@link MongoPersistentProperty}'s name.
|
||||
*
|
||||
* @since 1.3
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
public enum PropertyNameFieldNamingStrategy implements FieldNamingStrategy {
|
||||
|
||||
INSTANCE;
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.mongodb.core.mapping.FieldNamingStrategy#getFieldName(org.springframework.data.mongodb.core.mapping.MongoPersistentProperty)
|
||||
*/
|
||||
public String getFieldName(MongoPersistentProperty property) {
|
||||
return property.getName();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,167 @@
|
||||
/*
|
||||
* Copyright 2012-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.mapping;
|
||||
|
||||
import java.beans.PropertyDescriptor;
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.data.mapping.Association;
|
||||
import org.springframework.data.mapping.context.AbstractMappingContext;
|
||||
import org.springframework.data.mapping.model.AbstractPersistentProperty;
|
||||
import org.springframework.data.mapping.model.BasicPersistentEntity;
|
||||
import org.springframework.data.mapping.model.SimpleTypeHolder;
|
||||
import org.springframework.data.mongodb.MongoCollectionUtils;
|
||||
import org.springframework.data.util.TypeInformation;
|
||||
|
||||
/**
|
||||
* @deprecated use {@link MongoMappingContext} instead.
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
@Deprecated
|
||||
public class SimpleMongoMappingContext extends
|
||||
AbstractMappingContext<SimpleMongoMappingContext.SimpleMongoPersistentEntity<?>, MongoPersistentProperty> {
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.mapping.context.AbstractMappingContext#createPersistentEntity(org.springframework.data.util.TypeInformation)
|
||||
*/
|
||||
@Override
|
||||
protected <T> SimpleMongoPersistentEntity<T> createPersistentEntity(TypeInformation<T> typeInformation) {
|
||||
return new SimpleMongoPersistentEntity<T>(typeInformation);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.mapping.context.AbstractMappingContext#createPersistentProperty(java.lang.reflect.Field, java.beans.PropertyDescriptor, org.springframework.data.mapping.model.MutablePersistentEntity, org.springframework.data.mapping.model.SimpleTypeHolder)
|
||||
*/
|
||||
@Override
|
||||
protected SimplePersistentProperty createPersistentProperty(Field field, PropertyDescriptor descriptor,
|
||||
SimpleMongoPersistentEntity<?> owner, SimpleTypeHolder simpleTypeHolder) {
|
||||
return new SimplePersistentProperty(field, descriptor, owner, simpleTypeHolder);
|
||||
}
|
||||
|
||||
static class SimplePersistentProperty extends AbstractPersistentProperty<MongoPersistentProperty> implements
|
||||
MongoPersistentProperty {
|
||||
|
||||
private static final List<String> ID_FIELD_NAMES = Arrays.asList("id", "_id");
|
||||
|
||||
/**
|
||||
* Creates a new {@link SimplePersistentProperty}.
|
||||
*
|
||||
* @param field
|
||||
* @param propertyDescriptor
|
||||
* @param information
|
||||
*/
|
||||
public SimplePersistentProperty(Field field, PropertyDescriptor propertyDescriptor, MongoPersistentEntity<?> owner,
|
||||
SimpleTypeHolder simpleTypeHolder) {
|
||||
super(field, propertyDescriptor, owner, simpleTypeHolder);
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.springframework.data.mapping.BasicPersistentProperty#isIdProperty()
|
||||
*/
|
||||
public boolean isIdProperty() {
|
||||
return ID_FIELD_NAMES.contains(field.getName());
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.springframework.data.mongodb.core.core.mapping.MongoPersistentProperty#getKey()
|
||||
*/
|
||||
public String getFieldName() {
|
||||
return isIdProperty() ? "_id" : getName();
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.mongodb.core.core.mapping.MongoPersistentProperty#getFieldOrder()
|
||||
*/
|
||||
public int getFieldOrder() {
|
||||
return Integer.MAX_VALUE;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.springframework.data.mapping.AbstractPersistentProperty#createAssociation()
|
||||
*/
|
||||
@Override
|
||||
protected Association<MongoPersistentProperty> createAssociation() {
|
||||
return new Association<MongoPersistentProperty>(this, null);
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.springframework.data.mongodb.core.core.mapping.MongoPersistentProperty#isDbReference()
|
||||
*/
|
||||
public boolean isDbReference() {
|
||||
return false;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.springframework.data.mongodb.core.core.mapping.MongoPersistentProperty#getDBRef()
|
||||
*/
|
||||
public DBRef getDBRef() {
|
||||
return null;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.springframework.data.mongodb.core.core.mapping.MongoPersistentProperty#isVersion()
|
||||
*/
|
||||
public boolean isVersionProperty() {
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.mongodb.core.mapping.MongoPersistentProperty#usePropertyAccess()
|
||||
*/
|
||||
public boolean usePropertyAccess() {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
static class SimpleMongoPersistentEntity<T> extends BasicPersistentEntity<T, MongoPersistentProperty> implements
|
||||
MongoPersistentEntity<T> {
|
||||
|
||||
/**
|
||||
* @param information
|
||||
*/
|
||||
public SimpleMongoPersistentEntity(TypeInformation<T> information) {
|
||||
super(information);
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.springframework.data.mongodb.core.core.mapping.MongoPersistentEntity#getCollection()
|
||||
*/
|
||||
public String getCollection() {
|
||||
return MongoCollectionUtils.getPreferredCollectionName(getType());
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.springframework.data.mongodb.core.core.mapping.MongoPersistentEntity#getVersionProperty()
|
||||
*/
|
||||
public MongoPersistentProperty getVersionProperty() {
|
||||
return null;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.mongodb.core.mapping.MongoPersistentEntity#hasVersionProperty()
|
||||
*/
|
||||
public boolean hasVersionProperty() {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,50 +0,0 @@
|
||||
/*
|
||||
* Copyright 2013 by the original author(s).
|
||||
*
|
||||
* 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.mapping.event;
|
||||
|
||||
import com.mongodb.DBObject;
|
||||
|
||||
/**
|
||||
* Base class for delete events.
|
||||
*
|
||||
* @author Martin Baumgartner
|
||||
*/
|
||||
public abstract class AbstractDeleteEvent<T> extends MongoMappingEvent<DBObject> {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
private final Class<T> type;
|
||||
|
||||
/**
|
||||
* Creates a new {@link AbstractDeleteEvent} for the given {@link DBObject} and type.
|
||||
*
|
||||
* @param dbo must not be {@literal null}.
|
||||
* @param type , possibly be {@literal null}.
|
||||
*/
|
||||
public AbstractDeleteEvent(DBObject dbo, Class<T> type) {
|
||||
|
||||
super(dbo, dbo);
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the type for which the {@link AbstractDeleteEvent} shall be invoked for.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public Class<T> getType() {
|
||||
return type;
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2011-2013 by the original author(s).
|
||||
* Copyright 2011 by the original author(s).
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -27,7 +27,6 @@ import com.mongodb.DBObject;
|
||||
*
|
||||
* @author Jon Brisbin
|
||||
* @author Oliver Gierke
|
||||
* @author Martin Baumgartner
|
||||
*/
|
||||
public abstract class AbstractMongoEventListener<E> implements ApplicationListener<MongoMappingEvent<?>> {
|
||||
|
||||
@@ -46,7 +45,6 @@ public abstract class AbstractMongoEventListener<E> implements ApplicationListen
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.context.ApplicationListener#onApplicationEvent(org.springframework.context.ApplicationEvent)
|
||||
*/
|
||||
@SuppressWarnings("rawtypes")
|
||||
public void onApplicationEvent(MongoMappingEvent<?> event) {
|
||||
|
||||
if (event instanceof AfterLoadEvent) {
|
||||
@@ -59,22 +57,6 @@ public abstract class AbstractMongoEventListener<E> implements ApplicationListen
|
||||
return;
|
||||
}
|
||||
|
||||
if (event instanceof AbstractDeleteEvent) {
|
||||
|
||||
Class<?> eventDomainType = ((AbstractDeleteEvent) event).getType();
|
||||
|
||||
if (eventDomainType != null && domainClass.isAssignableFrom(eventDomainType)) {
|
||||
if (event instanceof BeforeDeleteEvent) {
|
||||
onBeforeDelete(event.getDBObject());
|
||||
}
|
||||
if (event instanceof AfterDeleteEvent) {
|
||||
onAfterDelete(event.getDBObject());
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
E source = (E) event.getSource();
|
||||
|
||||
@@ -96,43 +78,31 @@ public abstract class AbstractMongoEventListener<E> implements ApplicationListen
|
||||
|
||||
public void onBeforeConvert(E source) {
|
||||
if (LOG.isDebugEnabled()) {
|
||||
LOG.debug("onBeforeConvert({})", source);
|
||||
LOG.debug("onBeforeConvert(" + source + ")");
|
||||
}
|
||||
}
|
||||
|
||||
public void onBeforeSave(E source, DBObject dbo) {
|
||||
if (LOG.isDebugEnabled()) {
|
||||
LOG.debug("onBeforeSave({}, {})", source, dbo);
|
||||
LOG.debug("onBeforeSave(" + source + ", " + dbo + ")");
|
||||
}
|
||||
}
|
||||
|
||||
public void onAfterSave(E source, DBObject dbo) {
|
||||
if (LOG.isDebugEnabled()) {
|
||||
LOG.debug("onAfterSave({}, {})", source, dbo);
|
||||
LOG.debug("onAfterSave(" + source + ", " + dbo + ")");
|
||||
}
|
||||
}
|
||||
|
||||
public void onAfterLoad(DBObject dbo) {
|
||||
if (LOG.isDebugEnabled()) {
|
||||
LOG.debug("onAfterLoad({})", dbo);
|
||||
LOG.debug("onAfterLoad(" + dbo + ")");
|
||||
}
|
||||
}
|
||||
|
||||
public void onAfterConvert(DBObject dbo, E source) {
|
||||
if (LOG.isDebugEnabled()) {
|
||||
LOG.debug("onAfterConvert({}, {})", dbo, source);
|
||||
}
|
||||
}
|
||||
|
||||
public void onAfterDelete(DBObject dbo) {
|
||||
if (LOG.isDebugEnabled()) {
|
||||
LOG.debug("onAfterConvert({})", dbo);
|
||||
}
|
||||
}
|
||||
|
||||
public void onBeforeDelete(DBObject dbo) {
|
||||
if (LOG.isDebugEnabled()) {
|
||||
LOG.debug("onAfterConvert({})", dbo);
|
||||
LOG.debug("onAfterConvert(" + dbo + "," + source + ")");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,39 +0,0 @@
|
||||
/*
|
||||
* Copyright 2013 by the original author(s).
|
||||
*
|
||||
* 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.mapping.event;
|
||||
|
||||
import com.mongodb.DBObject;
|
||||
|
||||
/**
|
||||
* Event being thrown after a single or a set of documents has/have been deleted. The {@link DBObject} held in the event
|
||||
* will be the query document <em>after</am> it has been mapped onto the domain type handled.
|
||||
*
|
||||
* @author Martin Baumgartner
|
||||
*/
|
||||
public class AfterDeleteEvent<T> extends AbstractDeleteEvent<T> {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* Creates a new {@link AfterDeleteEvent} for the given {@link DBObject} and type.
|
||||
*
|
||||
* @param dbo must not be {@literal null}.
|
||||
* @param type can be {@literal null}.
|
||||
*/
|
||||
public AfterDeleteEvent(DBObject dbo, Class<T> type) {
|
||||
super(dbo, type);
|
||||
}
|
||||
}
|
||||
@@ -1,39 +0,0 @@
|
||||
/*
|
||||
* Copyright 2013 by the original author(s).
|
||||
*
|
||||
* 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.mapping.event;
|
||||
|
||||
import com.mongodb.DBObject;
|
||||
|
||||
/**
|
||||
* Event being thrown before a document is deleted. The {@link DBObject} held in the event will represent the query
|
||||
* document <em>before</em> being mapped based on the domain class handled.
|
||||
*
|
||||
* @author Martin Baumgartner
|
||||
*/
|
||||
public class BeforeDeleteEvent<T> extends AbstractDeleteEvent<T> {
|
||||
|
||||
private static final long serialVersionUID = -2627547705679734497L;
|
||||
|
||||
/**
|
||||
* Creates a new {@link BeforeDeleteEvent} for the given {@link DBObject} and type.
|
||||
*
|
||||
* @param dbo must not be {@literal null}.
|
||||
* @param type can be {@literal null}.
|
||||
*/
|
||||
public BeforeDeleteEvent(DBObject dbo, Class<T> type) {
|
||||
super(dbo, type);
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2011-2013 the original author or authors.
|
||||
* Copyright 2011-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.
|
||||
@@ -17,19 +17,15 @@ package org.springframework.data.mongodb.core.mapping.event;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.context.ApplicationListener;
|
||||
|
||||
import com.mongodb.DBObject;
|
||||
|
||||
/**
|
||||
* {@link ApplicationListener} for Mongo mapping events logging the events.
|
||||
*
|
||||
* @author Jon Brisbin
|
||||
* @author Martin Baumgartner
|
||||
* @author Jon Brisbin <jbrisbin@vmware.com>
|
||||
*/
|
||||
public class LoggingEventListener extends AbstractMongoEventListener<Object> {
|
||||
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger(LoggingEventListener.class);
|
||||
private static final Logger log = LoggerFactory.getLogger(LoggingEventListener.class);
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
@@ -37,7 +33,7 @@ public class LoggingEventListener extends AbstractMongoEventListener<Object> {
|
||||
*/
|
||||
@Override
|
||||
public void onBeforeConvert(Object source) {
|
||||
LOGGER.info("onBeforeConvert: {}", source);
|
||||
log.info("onBeforeConvert: " + source);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -46,7 +42,10 @@ public class LoggingEventListener extends AbstractMongoEventListener<Object> {
|
||||
*/
|
||||
@Override
|
||||
public void onBeforeSave(Object source, DBObject dbo) {
|
||||
LOGGER.info("onBeforeSave: {}, {}", source, dbo);
|
||||
try {
|
||||
log.info("onBeforeSave: " + source + ", " + dbo);
|
||||
} catch (Throwable ignored) {
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -55,7 +54,7 @@ public class LoggingEventListener extends AbstractMongoEventListener<Object> {
|
||||
*/
|
||||
@Override
|
||||
public void onAfterSave(Object source, DBObject dbo) {
|
||||
LOGGER.info("onAfterSave: {}, {}", source, dbo);
|
||||
log.info("onAfterSave: " + source + ", " + dbo);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -64,7 +63,7 @@ public class LoggingEventListener extends AbstractMongoEventListener<Object> {
|
||||
*/
|
||||
@Override
|
||||
public void onAfterLoad(DBObject dbo) {
|
||||
LOGGER.info("onAfterLoad: {}", dbo);
|
||||
log.info("onAfterLoad: " + dbo);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -73,24 +72,6 @@ public class LoggingEventListener extends AbstractMongoEventListener<Object> {
|
||||
*/
|
||||
@Override
|
||||
public void onAfterConvert(DBObject dbo, Object source) {
|
||||
LOGGER.info("onAfterConvert: {}, {}", dbo, source);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.mongodb.core.mapping.event.AbstractMongoEventListener#onAfterDelete(com.mongodb.DBObject)
|
||||
*/
|
||||
@Override
|
||||
public void onAfterDelete(DBObject dbo) {
|
||||
LOGGER.info("onAfterDelete: {}", dbo);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.mongodb.core.mapping.event.AbstractMongoEventListener#onBeforeDelete(com.mongodb.DBObject)
|
||||
*/
|
||||
@Override
|
||||
public void onBeforeDelete(DBObject dbo) {
|
||||
LOGGER.info("onBeforeDelete: {}", dbo);
|
||||
log.info("onAfterConvert: " + dbo + ", " + source);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2010-2013 the original author or authors.
|
||||
* Copyright 2010-2011 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.
|
||||
@@ -17,26 +17,15 @@ package org.springframework.data.mongodb.core.query;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.ObjectUtils;
|
||||
|
||||
import com.mongodb.BasicDBObject;
|
||||
import com.mongodb.DBObject;
|
||||
|
||||
/**
|
||||
* @author Thomas Risberg
|
||||
* @author Oliver Gierke
|
||||
* @author Patryk Wasik
|
||||
*/
|
||||
public class Field {
|
||||
|
||||
private final Map<String, Integer> criteria = new HashMap<String, Integer>();
|
||||
private final Map<String, Object> slices = new HashMap<String, Object>();
|
||||
private final Map<String, Criteria> elemMatchs = new HashMap<String, Criteria>();
|
||||
private String postionKey;
|
||||
private int positionValue;
|
||||
private Map<String, Integer> criteria = new HashMap<String, Integer>();
|
||||
|
||||
private Map<String, Object> slices = new HashMap<String, Object>();
|
||||
|
||||
public Field include(String key) {
|
||||
criteria.put(key, Integer.valueOf(1));
|
||||
@@ -58,104 +47,14 @@ public class Field {
|
||||
return this;
|
||||
}
|
||||
|
||||
public Field elemMatch(String key, Criteria elemMatchCriteria) {
|
||||
elemMatchs.put(key, elemMatchCriteria);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* The array field must appear in the query. Only one positional {@code $} operator can appear in the projection and
|
||||
* only one array field can appear in the query.
|
||||
*
|
||||
* @param field query array field, must not be {@literal null} or empty.
|
||||
* @param value
|
||||
* @return
|
||||
*/
|
||||
public Field position(String field, int value) {
|
||||
|
||||
Assert.hasText(field, "Field must not be null or empty!");
|
||||
|
||||
postionKey = field;
|
||||
positionValue = value;
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public DBObject getFieldsObject() {
|
||||
|
||||
DBObject dbo = new BasicDBObject();
|
||||
|
||||
for (String k : criteria.keySet()) {
|
||||
dbo.put(k, criteria.get(k));
|
||||
dbo.put(k, (criteria.get(k)));
|
||||
}
|
||||
|
||||
for (String k : slices.keySet()) {
|
||||
dbo.put(k, new BasicDBObject("$slice", slices.get(k)));
|
||||
dbo.put(k, new BasicDBObject("$slice", (slices.get(k))));
|
||||
}
|
||||
|
||||
for (Entry<String, Criteria> entry : elemMatchs.entrySet()) {
|
||||
DBObject dbObject = new BasicDBObject("$elemMatch", entry.getValue().getCriteriaObject());
|
||||
dbo.put(entry.getKey(), dbObject);
|
||||
}
|
||||
|
||||
if (postionKey != null) {
|
||||
dbo.put(postionKey + ".$", positionValue);
|
||||
}
|
||||
|
||||
return dbo;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see java.lang.Object#equals(java.lang.Object)
|
||||
*/
|
||||
@Override
|
||||
public boolean equals(Object object) {
|
||||
|
||||
if (this == object) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!(object instanceof Field)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
Field that = (Field) object;
|
||||
|
||||
if (!this.criteria.equals(that.criteria)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!this.slices.equals(that.slices)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!this.elemMatchs.equals(that.elemMatchs)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
boolean samePositionKey = this.postionKey == null ? that.postionKey == null : this.postionKey
|
||||
.equals(that.postionKey);
|
||||
boolean samePositionValue = this.positionValue == that.positionValue;
|
||||
|
||||
return samePositionKey && samePositionValue;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see java.lang.Object#hashCode()
|
||||
*/
|
||||
@Override
|
||||
public int hashCode() {
|
||||
|
||||
int result = 17;
|
||||
|
||||
result += 31 * ObjectUtils.nullSafeHashCode(this.criteria);
|
||||
result += 31 * ObjectUtils.nullSafeHashCode(this.elemMatchs);
|
||||
result += 31 * ObjectUtils.nullSafeHashCode(this.slices);
|
||||
result += 31 * ObjectUtils.nullSafeHashCode(this.postionKey);
|
||||
result += 31 * ObjectUtils.nullSafeHashCode(this.positionValue);
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2010-2013 the original author or authors.
|
||||
* Copyright 2010-2011 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.
|
||||
@@ -15,31 +15,11 @@
|
||||
*/
|
||||
package org.springframework.data.mongodb.core.query;
|
||||
|
||||
import org.springframework.data.domain.Sort.Direction;
|
||||
|
||||
/**
|
||||
* An enum that specifies the ordering for sort or index specifications
|
||||
*
|
||||
* @deprecated prefer {@link Direction}
|
||||
* @author Thomas Risberg
|
||||
* @author Oliver Gierke
|
||||
* @author trisberg
|
||||
*/
|
||||
@Deprecated
|
||||
public enum Order {
|
||||
|
||||
ASCENDING {
|
||||
@Override
|
||||
public Direction toDirection() {
|
||||
return Direction.ASC;
|
||||
}
|
||||
},
|
||||
|
||||
DESCENDING {
|
||||
@Override
|
||||
public Direction toDirection() {
|
||||
return Direction.DESC;
|
||||
}
|
||||
};
|
||||
|
||||
public abstract Direction toDirection();
|
||||
ASCENDING, DESCENDING
|
||||
}
|
||||
|
||||
@@ -24,7 +24,6 @@ import java.util.List;
|
||||
|
||||
import org.springframework.data.domain.Pageable;
|
||||
import org.springframework.data.domain.Sort;
|
||||
import org.springframework.data.domain.Sort.Order;
|
||||
import org.springframework.data.mongodb.InvalidMongoDbApiUsageException;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
@@ -39,7 +38,9 @@ public class Query {
|
||||
|
||||
private LinkedHashMap<String, Criteria> criteria = new LinkedHashMap<String, Criteria>();
|
||||
private Field fieldSpec;
|
||||
private Sort sort;
|
||||
private Sort coreSort;
|
||||
@SuppressWarnings("deprecation")
|
||||
private org.springframework.data.mongodb.core.query.Sort sort;
|
||||
private int skip;
|
||||
private int limit;
|
||||
private String hint;
|
||||
@@ -114,6 +115,21 @@ public class Query {
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a {@link org.springframework.data.mongodb.core.query.Sort} instance to define ordering properties.
|
||||
*
|
||||
* @deprecated use {@link #with(Sort)} instead
|
||||
* @return
|
||||
*/
|
||||
@Deprecated
|
||||
public org.springframework.data.mongodb.core.query.Sort sort() {
|
||||
if (this.sort == null) {
|
||||
this.sort = new org.springframework.data.mongodb.core.query.Sort();
|
||||
}
|
||||
|
||||
return this.sort;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the given pagination information on the {@link Query} instance. Will transparently set {@code skip} and
|
||||
* {@code limit} as well as applying the {@link Sort} instance defined with the {@link Pageable}.
|
||||
@@ -145,17 +161,10 @@ public class Query {
|
||||
return this;
|
||||
}
|
||||
|
||||
for (Order order : sort) {
|
||||
if (order.isIgnoreCase()) {
|
||||
throw new IllegalArgumentException(String.format("Gven sort contained an Order for %s with ignore case! "
|
||||
+ "MongoDB does not support sorting ignoreing case currently!", order.getProperty()));
|
||||
}
|
||||
}
|
||||
|
||||
if (this.sort == null) {
|
||||
this.sort = sort;
|
||||
if (this.coreSort == null) {
|
||||
this.coreSort = sort;
|
||||
} else {
|
||||
this.sort = this.sort.and(sort);
|
||||
this.coreSort = this.coreSort.and(sort);
|
||||
}
|
||||
|
||||
return this;
|
||||
@@ -178,20 +187,25 @@ public class Query {
|
||||
return fieldSpec.getFieldsObject();
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
public DBObject getSortObject() {
|
||||
|
||||
if (this.sort == null && this.sort == null) {
|
||||
if (this.coreSort == null && this.sort == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
DBObject dbo = new BasicDBObject();
|
||||
|
||||
if (this.sort != null) {
|
||||
for (org.springframework.data.domain.Sort.Order order : this.sort) {
|
||||
if (this.coreSort != null) {
|
||||
for (org.springframework.data.domain.Sort.Order order : this.coreSort) {
|
||||
dbo.put(order.getProperty(), order.isAscending() ? 1 : -1);
|
||||
}
|
||||
}
|
||||
|
||||
if (this.sort != null) {
|
||||
dbo.putAll(this.sort.getSortObject());
|
||||
}
|
||||
|
||||
return dbo;
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,56 @@
|
||||
/*
|
||||
* 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.
|
||||
* 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.query;
|
||||
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import com.mongodb.BasicDBObject;
|
||||
import com.mongodb.DBObject;
|
||||
|
||||
/**
|
||||
* Helper class to define sorting criterias for a Query instance.
|
||||
*
|
||||
* @author Thomas Risberg
|
||||
* @author Oliver Gierke
|
||||
* @deprecated use {@link org.springframework.data.domain.Sort} instead. See
|
||||
* {@link Query#with(org.springframework.data.domain.Sort)}.
|
||||
*/
|
||||
@Deprecated
|
||||
public class Sort {
|
||||
|
||||
private Map<String, Order> fieldSpec = new LinkedHashMap<String, Order>();
|
||||
|
||||
public Sort() {
|
||||
}
|
||||
|
||||
public Sort(String key, Order order) {
|
||||
fieldSpec.put(key, order);
|
||||
}
|
||||
|
||||
public Sort on(String key, Order order) {
|
||||
fieldSpec.put(key, order);
|
||||
return this;
|
||||
}
|
||||
|
||||
public DBObject getSortObject() {
|
||||
DBObject dbo = new BasicDBObject();
|
||||
for (String k : fieldSpec.keySet()) {
|
||||
dbo.put(k, fieldSpec.get(k).equals(Order.ASCENDING) ? 1 : -1);
|
||||
}
|
||||
return dbo;
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2011-2013 the original author or authors.
|
||||
* Copyright 2011 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.
|
||||
@@ -15,11 +15,7 @@
|
||||
*/
|
||||
package org.springframework.data.mongodb.repository;
|
||||
|
||||
import java.lang.annotation.Documented;
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
import java.lang.annotation.*;
|
||||
|
||||
/**
|
||||
* Annotation to declare finder queries directly on repository methods. Both attributes allow using a placeholder
|
||||
@@ -47,12 +43,4 @@ public @interface Query {
|
||||
* @return
|
||||
*/
|
||||
String fields() default "";
|
||||
|
||||
/**
|
||||
* Returns whether the query defined should be executed as count projection.
|
||||
*
|
||||
* @since 1.3
|
||||
* @return
|
||||
*/
|
||||
boolean count() default false;
|
||||
}
|
||||
|
||||
@@ -53,6 +53,14 @@ public class MongoRepositoryBean<T> extends CdiRepositoryBean<T> {
|
||||
this.operations = operations;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see javax.enterprise.inject.spi.Bean#getScope()
|
||||
*/
|
||||
public Class<? extends Annotation> getScope() {
|
||||
return operations.getScope();
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.repository.cdi.CdiRepositoryBean#create(javax.enterprise.context.spi.CreationalContext, java.lang.Class)
|
||||
|
||||
@@ -17,8 +17,6 @@ package org.springframework.data.mongodb.repository.query;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.core.convert.ConversionService;
|
||||
import org.springframework.core.convert.support.DefaultConversionService;
|
||||
import org.springframework.data.domain.PageImpl;
|
||||
import org.springframework.data.domain.Pageable;
|
||||
import org.springframework.data.mongodb.core.MongoOperations;
|
||||
@@ -41,8 +39,6 @@ import org.springframework.util.Assert;
|
||||
*/
|
||||
public abstract class AbstractMongoQuery implements RepositoryQuery {
|
||||
|
||||
private static final ConversionService CONVERSION_SERVICE = new DefaultConversionService();
|
||||
|
||||
private final MongoQueryMethod method;
|
||||
private final MongoOperations operations;
|
||||
|
||||
@@ -90,23 +86,19 @@ public abstract class AbstractMongoQuery implements RepositoryQuery {
|
||||
return new CollectionExecution(accessor.getPageable()).execute(query);
|
||||
} else if (method.isPageQuery()) {
|
||||
return new PagedExecution(accessor.getPageable()).execute(query);
|
||||
} else {
|
||||
return new SingleEntityExecution().execute(query);
|
||||
}
|
||||
|
||||
Object result = new SingleEntityExecution(isCountQuery()).execute(query);
|
||||
|
||||
if (result == null) {
|
||||
return result;
|
||||
}
|
||||
|
||||
Class<?> expectedReturnType = method.getReturnType().getType();
|
||||
|
||||
if (expectedReturnType.isAssignableFrom(result.getClass())) {
|
||||
return result;
|
||||
}
|
||||
|
||||
return CONVERSION_SERVICE.convert(result, expectedReturnType);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a {@link Query} instance using the given {@link ParameterAccessor}
|
||||
*
|
||||
* @param accessor must not be {@literal null}.
|
||||
* @return
|
||||
*/
|
||||
protected abstract Query createQuery(ConvertingParameterAccessor accessor);
|
||||
|
||||
/**
|
||||
* Creates a {@link Query} instance using the given {@link ConvertingParameterAccessor}. Will delegate to
|
||||
* {@link #createQuery(ConvertingParameterAccessor)} by default but allows customization of the count query to be
|
||||
@@ -119,21 +111,6 @@ public abstract class AbstractMongoQuery implements RepositoryQuery {
|
||||
return createQuery(accessor);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a {@link Query} instance using the given {@link ParameterAccessor}
|
||||
*
|
||||
* @param accessor must not be {@literal null}.
|
||||
* @return
|
||||
*/
|
||||
protected abstract Query createQuery(ConvertingParameterAccessor accessor);
|
||||
|
||||
/**
|
||||
* Returns whether the query should get a count projection applied.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
protected abstract boolean isCountQuery();
|
||||
|
||||
private abstract class Execution {
|
||||
|
||||
abstract Object execute(Query query);
|
||||
@@ -214,12 +191,6 @@ public abstract class AbstractMongoQuery implements RepositoryQuery {
|
||||
*/
|
||||
class SingleEntityExecution extends Execution {
|
||||
|
||||
private final boolean countProjection;
|
||||
|
||||
private SingleEntityExecution(boolean countProjection) {
|
||||
this.countProjection = countProjection;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.mongodb.repository.AbstractMongoQuery.Execution#execute(org.springframework.data.mongodb.core.core.query.Query)
|
||||
@@ -228,8 +199,7 @@ public abstract class AbstractMongoQuery implements RepositoryQuery {
|
||||
Object execute(Query query) {
|
||||
|
||||
MongoEntityMetadata<?> metadata = method.getEntityInformation();
|
||||
return countProjection ? operations.count(query, metadata.getJavaType()) : operations.findOne(query,
|
||||
metadata.getJavaType());
|
||||
return operations.findOne(query, metadata.getJavaType());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2010-2013 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.
|
||||
@@ -169,68 +169,68 @@ class MongoQueryCreator extends AbstractQueryCreator<Query, Criteria> {
|
||||
PotentiallyConvertingIterator parameters) {
|
||||
|
||||
switch (type) {
|
||||
case AFTER:
|
||||
case GREATER_THAN:
|
||||
return criteria.gt(parameters.nextConverted(property));
|
||||
case GREATER_THAN_EQUAL:
|
||||
return criteria.gte(parameters.nextConverted(property));
|
||||
case BEFORE:
|
||||
case LESS_THAN:
|
||||
return criteria.lt(parameters.nextConverted(property));
|
||||
case LESS_THAN_EQUAL:
|
||||
return criteria.lte(parameters.nextConverted(property));
|
||||
case BETWEEN:
|
||||
return criteria.gt(parameters.nextConverted(property)).lt(parameters.nextConverted(property));
|
||||
case IS_NOT_NULL:
|
||||
return criteria.ne(null);
|
||||
case IS_NULL:
|
||||
return criteria.is(null);
|
||||
case NOT_IN:
|
||||
return criteria.nin(nextAsArray(parameters, property));
|
||||
case IN:
|
||||
return criteria.in(nextAsArray(parameters, property));
|
||||
case LIKE:
|
||||
case STARTING_WITH:
|
||||
case ENDING_WITH:
|
||||
case CONTAINING:
|
||||
String value = parameters.next().toString();
|
||||
return criteria.regex(toLikeRegex(value, type));
|
||||
case REGEX:
|
||||
return criteria.regex(parameters.next().toString());
|
||||
case EXISTS:
|
||||
return criteria.exists((Boolean) parameters.next());
|
||||
case TRUE:
|
||||
return criteria.is(true);
|
||||
case FALSE:
|
||||
return criteria.is(false);
|
||||
case NEAR:
|
||||
case AFTER:
|
||||
case GREATER_THAN:
|
||||
return criteria.gt(parameters.nextConverted(property));
|
||||
case GREATER_THAN_EQUAL:
|
||||
return criteria.gte(parameters.nextConverted(property));
|
||||
case BEFORE:
|
||||
case LESS_THAN:
|
||||
return criteria.lt(parameters.nextConverted(property));
|
||||
case LESS_THAN_EQUAL:
|
||||
return criteria.lte(parameters.nextConverted(property));
|
||||
case BETWEEN:
|
||||
return criteria.gt(parameters.nextConverted(property)).lt(parameters.nextConverted(property));
|
||||
case IS_NOT_NULL:
|
||||
return criteria.ne(null);
|
||||
case IS_NULL:
|
||||
return criteria.is(null);
|
||||
case NOT_IN:
|
||||
return criteria.nin(nextAsArray(parameters, property));
|
||||
case IN:
|
||||
return criteria.in(nextAsArray(parameters, property));
|
||||
case LIKE:
|
||||
case STARTING_WITH:
|
||||
case ENDING_WITH:
|
||||
case CONTAINING:
|
||||
String value = parameters.next().toString();
|
||||
return criteria.regex(toLikeRegex(value, type));
|
||||
case REGEX:
|
||||
return criteria.regex(parameters.next().toString());
|
||||
case EXISTS:
|
||||
return criteria.exists((Boolean) parameters.next());
|
||||
case TRUE:
|
||||
return criteria.is(true);
|
||||
case FALSE:
|
||||
return criteria.is(false);
|
||||
case NEAR:
|
||||
|
||||
Distance distance = accessor.getMaxDistance();
|
||||
Point point = accessor.getGeoNearLocation();
|
||||
point = point == null ? nextAs(parameters, Point.class) : point;
|
||||
Distance distance = accessor.getMaxDistance();
|
||||
Point point = accessor.getGeoNearLocation();
|
||||
point = point == null ? nextAs(parameters, Point.class) : point;
|
||||
|
||||
if (distance == null) {
|
||||
return criteria.near(point);
|
||||
if (distance == null) {
|
||||
return criteria.near(point);
|
||||
} else {
|
||||
if (distance.getMetric() != null) {
|
||||
criteria.nearSphere(point);
|
||||
} else {
|
||||
if (distance.getMetric() != null) {
|
||||
criteria.nearSphere(point);
|
||||
} else {
|
||||
criteria.near(point);
|
||||
}
|
||||
criteria.maxDistance(distance.getNormalizedValue());
|
||||
criteria.near(point);
|
||||
}
|
||||
return criteria;
|
||||
criteria.maxDistance(distance.getNormalizedValue());
|
||||
}
|
||||
return criteria;
|
||||
|
||||
case WITHIN:
|
||||
Object parameter = parameters.next();
|
||||
return criteria.within((Shape) parameter);
|
||||
case SIMPLE_PROPERTY:
|
||||
return criteria.is(parameters.nextConverted(property));
|
||||
case NEGATING_SIMPLE_PROPERTY:
|
||||
return criteria.ne(parameters.nextConverted(property));
|
||||
default:
|
||||
throw new IllegalArgumentException("Unsupported keyword!");
|
||||
case WITHIN:
|
||||
Object parameter = parameters.next();
|
||||
return criteria.within((Shape) parameter);
|
||||
case SIMPLE_PROPERTY:
|
||||
return criteria.is(parameters.nextConverted(property));
|
||||
case NEGATING_SIMPLE_PROPERTY:
|
||||
return criteria.ne(parameters.nextConverted(property));
|
||||
}
|
||||
|
||||
throw new IllegalArgumentException("Unsupported keyword!");
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -268,16 +268,15 @@ class MongoQueryCreator extends AbstractQueryCreator<Query, Criteria> {
|
||||
private String toLikeRegex(String source, Type type) {
|
||||
|
||||
switch (type) {
|
||||
case STARTING_WITH:
|
||||
source = source + "*";
|
||||
break;
|
||||
case ENDING_WITH:
|
||||
source = "*" + source;
|
||||
break;
|
||||
case CONTAINING:
|
||||
source = "*" + source + "*";
|
||||
break;
|
||||
default:
|
||||
case STARTING_WITH:
|
||||
source = source + "*";
|
||||
break;
|
||||
case ENDING_WITH:
|
||||
source = "*" + source;
|
||||
break;
|
||||
case CONTAINING:
|
||||
source = "*" + source + "*";
|
||||
break;
|
||||
}
|
||||
|
||||
return source.replaceAll("\\*", ".*");
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2011-2013 the original author or authors.
|
||||
* Copyright 2011-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.
|
||||
@@ -171,7 +171,7 @@ public class MongoQueryMethod extends QueryMethod {
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
Query getQueryAnnotation() {
|
||||
private Query getQueryAnnotation() {
|
||||
return method.getAnnotation(Query.class);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2013 the original author or authors.
|
||||
* Copyright 2002-2010 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.
|
||||
@@ -77,13 +77,4 @@ public class PartTreeMongoQuery extends AbstractMongoQuery {
|
||||
protected Query createCountQuery(ConvertingParameterAccessor accessor) {
|
||||
return new MongoQueryCreator(tree, accessor, context, false).createQuery();
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.mongodb.repository.query.AbstractMongoQuery#isCountQuery()
|
||||
*/
|
||||
@Override
|
||||
protected boolean isCountQuery() {
|
||||
return tree.isCountProjection();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2010-2013 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.
|
||||
@@ -15,7 +15,10 @@
|
||||
*/
|
||||
package org.springframework.data.mongodb.repository.query;
|
||||
|
||||
import org.springframework.data.domain.Pageable;
|
||||
import org.springframework.data.domain.Sort;
|
||||
import org.springframework.data.domain.Sort.Order;
|
||||
import org.springframework.data.mongodb.core.query.Query;
|
||||
|
||||
import com.mongodb.DBCursor;
|
||||
|
||||
@@ -24,7 +27,6 @@ import com.mongodb.DBCursor;
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
@Deprecated
|
||||
public abstract class QueryUtils {
|
||||
|
||||
private QueryUtils() {
|
||||
@@ -32,13 +34,51 @@ public abstract class QueryUtils {
|
||||
}
|
||||
|
||||
/**
|
||||
* Turns an {@link Order} into an {@link org.springframework.data.mongodb.core.query.Order}.
|
||||
* Applies the given {@link Pageable} to the given {@link Query}. Will do nothing if {@link Pageable} is
|
||||
* {@literal null}.
|
||||
*
|
||||
* @deprecated use {@link Order} directly.
|
||||
* @param order
|
||||
* @deprecated use {@link Query#with(Pageable)}.
|
||||
* @param query must not be {@literal null}.
|
||||
* @param pageable
|
||||
* @return
|
||||
*/
|
||||
@Deprecated
|
||||
public static Query applyPagination(Query query, Pageable pageable) {
|
||||
|
||||
if (pageable == null) {
|
||||
return query;
|
||||
}
|
||||
|
||||
query.limit(pageable.getPageSize());
|
||||
query.skip(pageable.getOffset());
|
||||
|
||||
return query.with(pageable.getSort());
|
||||
}
|
||||
|
||||
/**
|
||||
* Applies the given {@link Sort} to the {@link Query}. Will do nothing if {@link Sort} is {@literal null}.
|
||||
*
|
||||
* @deprecated use {@link Query#with(Pageable)}.
|
||||
* @param query must not be {@literal null}.
|
||||
* @param sort
|
||||
* @return
|
||||
*/
|
||||
@Deprecated
|
||||
public static Query applySorting(Query query, Sort sort) {
|
||||
|
||||
if (sort == null) {
|
||||
return query;
|
||||
}
|
||||
|
||||
org.springframework.data.mongodb.core.query.Sort bSort = query.sort();
|
||||
|
||||
for (Order order : sort) {
|
||||
bSort.on(order.getProperty(), toOrder(order));
|
||||
}
|
||||
|
||||
return query;
|
||||
}
|
||||
|
||||
public static org.springframework.data.mongodb.core.query.Order toOrder(Order order) {
|
||||
return order.isAscending() ? org.springframework.data.mongodb.core.query.Order.ASCENDING
|
||||
: org.springframework.data.mongodb.core.query.Order.DESCENDING;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2011-2013 the original author or authors.
|
||||
* Copyright 2011-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.
|
||||
@@ -38,21 +38,17 @@ public class StringBasedMongoQuery extends AbstractMongoQuery {
|
||||
|
||||
private final String query;
|
||||
private final String fieldSpec;
|
||||
private final boolean isCountQuery;
|
||||
|
||||
/**
|
||||
* Creates a new {@link StringBasedMongoQuery}.
|
||||
*
|
||||
* @param method must not be {@literal null}.
|
||||
* @param template must not be {@literal null}.
|
||||
* @param method
|
||||
* @param template
|
||||
*/
|
||||
public StringBasedMongoQuery(String query, MongoQueryMethod method, MongoOperations mongoOperations) {
|
||||
|
||||
super(method, mongoOperations);
|
||||
|
||||
this.query = query;
|
||||
this.fieldSpec = method.getFieldSpecification();
|
||||
this.isCountQuery = method.hasAnnotatedQuery() ? method.getQueryAnnotation().count() : false;
|
||||
}
|
||||
|
||||
public StringBasedMongoQuery(MongoQueryMethod method, MongoOperations mongoOperations) {
|
||||
@@ -86,15 +82,6 @@ public class StringBasedMongoQuery extends AbstractMongoQuery {
|
||||
return query;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.mongodb.repository.query.AbstractMongoQuery#isCountQuery()
|
||||
*/
|
||||
@Override
|
||||
protected boolean isCountQuery() {
|
||||
return isCountQuery;
|
||||
}
|
||||
|
||||
private String replacePlaceholders(String input, ConvertingParameterAccessor accessor) {
|
||||
|
||||
Matcher matcher = PLACEHOLDER.matcher(input);
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2011-2013 the original author or authors.
|
||||
* Copyright 2011-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.
|
||||
@@ -22,11 +22,12 @@ import java.util.Set;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.data.domain.Sort;
|
||||
import org.springframework.data.domain.Sort.Direction;
|
||||
import org.springframework.data.mongodb.core.MongoOperations;
|
||||
import org.springframework.data.mongodb.core.index.Index;
|
||||
import org.springframework.data.mongodb.core.query.Order;
|
||||
import org.springframework.data.mongodb.repository.query.MongoEntityMetadata;
|
||||
import org.springframework.data.mongodb.repository.query.PartTreeMongoQuery;
|
||||
import org.springframework.data.mongodb.repository.query.QueryUtils;
|
||||
import org.springframework.data.repository.core.support.QueryCreationListener;
|
||||
import org.springframework.data.repository.query.parser.Part;
|
||||
import org.springframework.data.repository.query.parser.Part.Type;
|
||||
@@ -73,14 +74,14 @@ class IndexEnsuringQueryCreationListener implements QueryCreationListener<PartTr
|
||||
return;
|
||||
}
|
||||
String property = part.getProperty().toDotPath();
|
||||
Direction order = toDirection(sort, property);
|
||||
Order order = toOrder(sort, property);
|
||||
index.on(property, order);
|
||||
}
|
||||
|
||||
// Add fixed sorting criteria to index
|
||||
if (sort != null) {
|
||||
for (Sort.Order order : sort) {
|
||||
index.on(order.getProperty(), order.getDirection());
|
||||
index.on(order.getProperty(), QueryUtils.toOrder(order));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -89,13 +90,13 @@ class IndexEnsuringQueryCreationListener implements QueryCreationListener<PartTr
|
||||
LOG.debug(String.format("Created %s!", index));
|
||||
}
|
||||
|
||||
private static Direction toDirection(Sort sort, String property) {
|
||||
private static Order toOrder(Sort sort, String property) {
|
||||
|
||||
if (sort == null) {
|
||||
return Direction.DESC;
|
||||
return Order.DESCENDING;
|
||||
}
|
||||
|
||||
org.springframework.data.domain.Sort.Order order = sort.getOrderFor(property);
|
||||
return order == null ? Direction.DESC : order.isAscending() ? Direction.ASC : Direction.DESC;
|
||||
return order == null ? Order.DESCENDING : order.isAscending() ? Order.ASCENDING : Order.DESCENDING;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2011-2013 the original author or authors.
|
||||
* Copyright 2011 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.
|
||||
@@ -39,6 +39,7 @@ import com.mysema.query.apt.DefaultConfiguration;
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
@SuppressWarnings("restriction")
|
||||
@SupportedAnnotationTypes({ "com.mysema.query.annotations.*", "org.springframework.data.mongodb.core.mapping.*" })
|
||||
@SupportedSourceVersion(SourceVersion.RELEASE_6)
|
||||
public class MongoAnnotationProcessor extends AbstractQuerydslProcessor {
|
||||
|
||||
@@ -49,14 +49,13 @@ public class SimpleMongoRepository<T, ID extends Serializable> implements MongoR
|
||||
/**
|
||||
* Creates a ew {@link SimpleMongoRepository} for the given {@link MongoEntityInformation} and {@link MongoTemplate}.
|
||||
*
|
||||
* @param metadata must not be {@literal null}.
|
||||
* @param template must not be {@literal null}.
|
||||
* @param metadata
|
||||
* @param template
|
||||
*/
|
||||
public SimpleMongoRepository(MongoEntityInformation<T, ID> metadata, MongoOperations mongoOperations) {
|
||||
|
||||
Assert.notNull(mongoOperations);
|
||||
Assert.notNull(metadata);
|
||||
|
||||
this.entityInformation = metadata;
|
||||
this.mongoOperations = mongoOperations;
|
||||
}
|
||||
@@ -97,7 +96,7 @@ public class SimpleMongoRepository<T, ID extends Serializable> implements MongoR
|
||||
*/
|
||||
public T findOne(ID id) {
|
||||
Assert.notNull(id, "The given id must not be null!");
|
||||
return mongoOperations.findById(id, entityInformation.getJavaType(), entityInformation.getCollectionName());
|
||||
return mongoOperations.findById(id, entityInformation.getJavaType());
|
||||
}
|
||||
|
||||
private Query getIdQuery(Object id) {
|
||||
@@ -115,8 +114,11 @@ public class SimpleMongoRepository<T, ID extends Serializable> implements MongoR
|
||||
public boolean exists(ID id) {
|
||||
|
||||
Assert.notNull(id, "The given id must not be null!");
|
||||
return mongoOperations.exists(getIdQuery(id), entityInformation.getJavaType(),
|
||||
entityInformation.getCollectionName());
|
||||
|
||||
final Query idQuery = getIdQuery(id);
|
||||
idQuery.fields();
|
||||
|
||||
return mongoOperations.findOne(idQuery, entityInformation.getJavaType(), entityInformation.getCollectionName()) != null;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -124,6 +126,7 @@ public class SimpleMongoRepository<T, ID extends Serializable> implements MongoR
|
||||
* @see org.springframework.data.repository.CrudRepository#count()
|
||||
*/
|
||||
public long count() {
|
||||
|
||||
return mongoOperations.getCollection(entityInformation.getCollectionName()).count();
|
||||
}
|
||||
|
||||
@@ -133,7 +136,7 @@ public class SimpleMongoRepository<T, ID extends Serializable> implements MongoR
|
||||
*/
|
||||
public void delete(ID id) {
|
||||
Assert.notNull(id, "The given id must not be null!");
|
||||
mongoOperations.remove(getIdQuery(id), entityInformation.getJavaType(), entityInformation.getCollectionName());
|
||||
mongoOperations.remove(getIdQuery(id), entityInformation.getJavaType());
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -163,6 +166,7 @@ public class SimpleMongoRepository<T, ID extends Serializable> implements MongoR
|
||||
* @see org.springframework.data.repository.CrudRepository#deleteAll()
|
||||
*/
|
||||
public void deleteAll() {
|
||||
|
||||
mongoOperations.remove(new Query(), entityInformation.getCollectionName());
|
||||
}
|
||||
|
||||
@@ -223,6 +227,7 @@ public class SimpleMongoRepository<T, ID extends Serializable> implements MongoR
|
||||
* @return
|
||||
*/
|
||||
protected MongoOperations getMongoOperations() {
|
||||
|
||||
return this.mongoOperations;
|
||||
}
|
||||
|
||||
@@ -230,6 +235,7 @@ public class SimpleMongoRepository<T, ID extends Serializable> implements MongoR
|
||||
* @return the entityInformation
|
||||
*/
|
||||
protected MongoEntityInformation<T, ID> getEntityInformation() {
|
||||
|
||||
return entityInformation;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -63,8 +63,7 @@ class SpringDataMongodbSerializer extends MongodbSerializer {
|
||||
|
||||
Path<?> parent = metadata.getParent();
|
||||
MongoPersistentEntity<?> entity = mappingContext.getPersistentEntity(parent.getType());
|
||||
MongoPersistentProperty property = entity.getPersistentProperty(metadata.getName());
|
||||
|
||||
MongoPersistentProperty property = entity.getPersistentProperty(metadata.getExpression().toString());
|
||||
return property == null ? super.getKeyForPath(expr, metadata) : property.getFieldName();
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
http\://www.springframework.org/schema/data/mongo/spring-mongo-1.0.xsd=org/springframework/data/mongodb/config/spring-mongo-1.0.xsd
|
||||
http\://www.springframework.org/schema/data/mongo/spring-mongo-1.1.xsd=org/springframework/data/mongodb/config/spring-mongo-1.1.xsd
|
||||
http\://www.springframework.org/schema/data/mongo/spring-mongo-1.2.xsd=org/springframework/data/mongodb/config/spring-mongo-1.2.xsd
|
||||
http\://www.springframework.org/schema/data/mongo/spring-mongo-1.3.xsd=org/springframework/data/mongodb/config/spring-mongo-1.3.xsd
|
||||
http\://www.springframework.org/schema/data/mongo/spring-mongo.xsd=org/springframework/data/mongodb/config/spring-mongo-1.3.xsd
|
||||
http\://www.springframework.org/schema/data/mongo/spring-mongo.xsd=org/springframework/data/mongodb/config/spring-mongo-1.2.xsd
|
||||
|
||||
@@ -1,597 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<xsd:schema xmlns="http://www.springframework.org/schema/data/mongo"
|
||||
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:beans="http://www.springframework.org/schema/beans"
|
||||
xmlns:tool="http://www.springframework.org/schema/tool"
|
||||
xmlns:context="http://www.springframework.org/schema/context"
|
||||
xmlns:repository="http://www.springframework.org/schema/data/repository"
|
||||
targetNamespace="http://www.springframework.org/schema/data/mongo"
|
||||
elementFormDefault="qualified" attributeFormDefault="unqualified">
|
||||
|
||||
<xsd:import namespace="http://www.springframework.org/schema/beans" />
|
||||
<xsd:import namespace="http://www.springframework.org/schema/tool" />
|
||||
<xsd:import namespace="http://www.springframework.org/schema/context" />
|
||||
<xsd:import namespace="http://www.springframework.org/schema/data/repository"
|
||||
schemaLocation="http://www.springframework.org/schema/data/repository/spring-repository.xsd" />
|
||||
|
||||
<xsd:element name="mongo" type="mongoType">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation source="org.springframework.data.mongodb.core.core.MongoFactoryBean"><![CDATA[
|
||||
Defines a Mongo instance used for accessing MongoDB'.
|
||||
]]></xsd:documentation>
|
||||
<xsd:appinfo>
|
||||
<tool:annotation>
|
||||
<tool:exports type="com.mongodb.Mongo"/>
|
||||
</tool:annotation>
|
||||
</xsd:appinfo>
|
||||
</xsd:annotation>
|
||||
</xsd:element>
|
||||
|
||||
<xsd:element name="db-factory">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
Defines a MongoDbFactory for connecting to a specific database
|
||||
]]></xsd:documentation>
|
||||
</xsd:annotation>
|
||||
<xsd:complexType>
|
||||
<xsd:attribute name="id" type="xsd:string" use="optional">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
The name of the mongo definition (by default "mongoDbFactory").]]></xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="mongo-ref" type="mongoRef" use="optional">
|
||||
<xsd:annotation>
|
||||
<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>
|
||||
<xsd:attribute name="dbname" type="xsd:string" use="optional">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
The name of the database to connect to. Default is 'db'.
|
||||
]]></xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="port" type="xsd:string" use="optional">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
The port to connect to MongoDB server. Default is 27017
|
||||
]]></xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="host" type="xsd:string" use="optional">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
The host to connect to a MongoDB server. Default is localhost
|
||||
]]></xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="username" type="xsd:string" use="optional">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
The username to use when connecting to a MongoDB server.
|
||||
]]></xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="password" type="xsd:string" use="optional">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
The password to use when connecting to a MongoDB server.
|
||||
]]></xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="uri" type="xsd:string" use="optional">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
The Mongo URI string.]]></xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="write-concern">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation>
|
||||
The WriteConcern that will be the default value used when asking the MongoDbFactory for a DB object
|
||||
</xsd:documentation>
|
||||
</xsd:annotation>
|
||||
<xsd:simpleType>
|
||||
<xsd:union memberTypes="writeConcernEnumeration xsd:string"/>
|
||||
</xsd:simpleType>
|
||||
</xsd:attribute>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
|
||||
<xsd:attributeGroup name="mongo-repository-attributes">
|
||||
<xsd:attribute name="mongo-template-ref" type="mongoTemplateRef" default="mongoTemplate">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation>
|
||||
The reference to a MongoTemplate. Will default to 'mongoTemplate'.
|
||||
</xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="create-query-indexes" type="xsd:boolean" default="false">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation>
|
||||
Enables creation of indexes for queries that get derived from the method name
|
||||
and thus reference domain class properties. Defaults to false.
|
||||
</xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
</xsd:attributeGroup>
|
||||
|
||||
<xsd:element name="repositories">
|
||||
<xsd:complexType>
|
||||
<xsd:complexContent>
|
||||
<xsd:extension base="repository:repositories">
|
||||
<xsd:attributeGroup ref="mongo-repository-attributes"/>
|
||||
<xsd:attributeGroup ref="repository:repository-attributes"/>
|
||||
</xsd:extension>
|
||||
</xsd:complexContent>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
|
||||
<xsd:element name="mapping-converter">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[Defines a MongoConverter for getting rich mapping functionality.]]></xsd:documentation>
|
||||
<xsd:appinfo>
|
||||
<tool:exports type="org.springframework.data.mongodb.core.convert.MappingMongoConverter" />
|
||||
</xsd:appinfo>
|
||||
</xsd:annotation>
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="custom-converters" minOccurs="0">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
Top-level element that contains one or more custom converters to be used for mapping
|
||||
domain objects to and from Mongo's DBObject]]>
|
||||
</xsd:documentation>
|
||||
</xsd:annotation>
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="converter" type="customConverterType" minOccurs="0" maxOccurs="unbounded"/>
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="base-package" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="id" type="xsd:string" use="optional">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
The name of the MappingMongoConverter instance (by default "mappingConverter").]]></xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="base-package" type="xsd:string" use="optional">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
The base package in which to scan for entities annotated with @Document
|
||||
]]></xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="db-factory-ref" type="xsd:string" use="optional">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation>
|
||||
The reference to a DbFactory.
|
||||
</xsd:documentation>
|
||||
<xsd:appinfo>
|
||||
<tool:annotation kind="ref">
|
||||
<tool:assignable-to type="org.springframework.data.mongodb.MongoDbFactory" />
|
||||
</tool:annotation>
|
||||
</xsd:appinfo>
|
||||
</xsd:annotation>
|
||||
</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>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="mapping-context-ref" type="mappingContextRef" use="optional">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation source="org.springframework.data.mapping.model.MappingContext">
|
||||
The reference to a MappingContext. Will default to 'mappingContext'.
|
||||
</xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="mongo-template-ref" type="mongoTemplateRef" use="optional">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation source="org.springframework.data.mongodb.core.core.MongoTemplate">
|
||||
The reference to a MongoTemplate. Will default to 'mongoTemplate'.
|
||||
</xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="disable-validation" use="optional">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation source="org.springframework.data.mongodb.core.mapping.event.ValidatingMongoEventListener">
|
||||
Disables JSR-303 validation on MongoDB documents before they are saved. By default it is set to false.
|
||||
</xsd:documentation>
|
||||
</xsd:annotation>
|
||||
<xsd:simpleType>
|
||||
<xsd:union memberTypes="xsd:boolean xsd:string"/>
|
||||
</xsd:simpleType>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="abbreviate-field-names" use="optional" default="false">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation source="org.springframework.data.mongodb.core.mapping.CamelCaseAbbreviatingFieldNamingStrategy">
|
||||
Enables abbreviating the field names for domain class properties to the
|
||||
first character of their camel case names, e.g. fooBar -> fb.
|
||||
</xsd:documentation>
|
||||
</xsd:annotation>
|
||||
<xsd:simpleType>
|
||||
<xsd:union memberTypes="xsd:boolean xsd:string"/>
|
||||
</xsd:simpleType>
|
||||
</xsd:attribute>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
|
||||
<xsd:element name="jmx">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
Defines a JMX Model MBeans for monitoring a MongoDB server'.
|
||||
]]></xsd:documentation>
|
||||
</xsd:annotation>
|
||||
<xsd:complexType>
|
||||
<xsd:attribute name="mongo-ref" type="mongoRef" use="optional">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
The name of the Mongo object that determines what server to monitor. (by default "mongo").]]></xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
|
||||
<xsd:element name="auditing">
|
||||
<xsd:annotation>
|
||||
<xsd:appinfo>
|
||||
<tool:annotation>
|
||||
<tool:exports type="org.springframework.data.mongodb.core.mapping.event.AuditingEventListener" />
|
||||
<tool:exports type="org.springframework.data.auditing.IsNewAwareAuditingHandler" />
|
||||
</tool:annotation>
|
||||
</xsd:appinfo>
|
||||
</xsd:annotation>
|
||||
<xsd:complexType>
|
||||
<xsd:attributeGroup ref="repository:auditing-attributes" />
|
||||
<xsd:attribute name="mapping-context-ref" type="mappingContextRef" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
|
||||
<xsd:simpleType name="mappingContextRef">
|
||||
<xsd:annotation>
|
||||
<xsd:appinfo>
|
||||
<tool:annotation kind="ref">
|
||||
<tool:assignable-to type="org.springframework.data.mapping.model.MappingContext"/>
|
||||
</tool:annotation>
|
||||
</xsd:appinfo>
|
||||
</xsd:annotation>
|
||||
<xsd:union memberTypes="xsd:string"/>
|
||||
</xsd:simpleType>
|
||||
|
||||
<xsd:simpleType name="mongoTemplateRef">
|
||||
<xsd:annotation>
|
||||
<xsd:appinfo>
|
||||
<tool:annotation kind="ref">
|
||||
<tool:assignable-to type="org.springframework.data.mongodb.core.core.MongoTemplate"/>
|
||||
</tool:annotation>
|
||||
</xsd:appinfo>
|
||||
</xsd:annotation>
|
||||
<xsd:union memberTypes="xsd:string"/>
|
||||
</xsd:simpleType>
|
||||
|
||||
<xsd:simpleType name="mongoRef">
|
||||
<xsd:annotation>
|
||||
<xsd:appinfo>
|
||||
<tool:annotation kind="ref">
|
||||
<tool:assignable-to type="org.springframework.data.mongodb.core.core.MongoFactoryBean"/>
|
||||
</tool:annotation>
|
||||
</xsd:appinfo>
|
||||
</xsd:annotation>
|
||||
<xsd:union memberTypes="xsd:string"/>
|
||||
</xsd:simpleType>
|
||||
|
||||
<xsd:simpleType name="writeConcernEnumeration">
|
||||
<xsd:restriction base="xsd:token">
|
||||
<xsd:enumeration value="NONE" />
|
||||
<xsd:enumeration value="NORMAL" />
|
||||
<xsd:enumeration value="SAFE" />
|
||||
<xsd:enumeration value="FSYNC_SAFE" />
|
||||
<xsd:enumeration value="REPLICAS_SAFE" />
|
||||
<xsd:enumeration value="JOURNAL_SAFE" />
|
||||
<xsd:enumeration value="MAJORITY" />
|
||||
</xsd:restriction>
|
||||
</xsd:simpleType>
|
||||
<!-- MLP
|
||||
<xsd:attributeGroup name="writeConcern">
|
||||
<xsd:attribute name="write-concern">
|
||||
<xsd:simpleType>
|
||||
<xsd:restriction base="xsd:string">
|
||||
<xsd:enumeration value="NONE" />
|
||||
<xsd:enumeration value="NORMAL" />
|
||||
<xsd:enumeration value="SAFE" />
|
||||
<xsd:enumeration value="FSYNC_SAFE" />
|
||||
<xsd:enumeration value="REPLICA_SAFE" />
|
||||
<xsd:enumeration value="JOURNAL_SAFE" />
|
||||
<xsd:enumeration value="MAJORITY" />
|
||||
</xsd:restriction>
|
||||
</xsd:simpleType>
|
||||
</xsd:attribute>
|
||||
</xsd:attributeGroup>
|
||||
-->
|
||||
<xsd:complexType name="mongoType">
|
||||
<xsd:sequence minOccurs="0" maxOccurs="1">
|
||||
<xsd:element name="options" type="optionsType">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
The Mongo driver options
|
||||
]]></xsd:documentation>
|
||||
<xsd:appinfo>
|
||||
<tool:annotation>
|
||||
<tool:exports type="com.mongodb.MongoOptions"/>
|
||||
</tool:annotation>
|
||||
</xsd:appinfo>
|
||||
</xsd:annotation>
|
||||
</xsd:element>
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="write-concern">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation>
|
||||
The WriteConcern that will be the default value used when asking the MongoDbFactory for a DB object
|
||||
</xsd:documentation>
|
||||
</xsd:annotation>
|
||||
<xsd:simpleType>
|
||||
<xsd:union memberTypes="writeConcernEnumeration xsd:string"/>
|
||||
</xsd:simpleType>
|
||||
</xsd:attribute>
|
||||
<!-- MLP
|
||||
<xsd:attributeGroup ref="writeConcern" />
|
||||
-->
|
||||
<xsd:attribute name="id" type="xsd:string" use="optional">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
The name of the mongo definition (by default "mongo").]]></xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="port" type="xsd:string" use="optional">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
The port to connect to MongoDB server. Default is 27017
|
||||
]]></xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="host" type="xsd:string" use="optional">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
The host to connect to a MongoDB server. Default is localhost
|
||||
]]></xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="replica-set" type="xsd:string" use="optional">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
The comma delimited list of host:port entries to use for replica set/pairs.
|
||||
]]></xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
</xsd:complexType>
|
||||
|
||||
<xsd:complexType name="optionsType">
|
||||
<xsd:attribute name="connections-per-host" type="xsd:string">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
The number of connections allowed per host. Will block if run out. Default is 10. System property MONGO.POOLSIZE can override
|
||||
]]></xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="threads-allowed-to-block-for-connection-multiplier" type="xsd:string">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
The multiplier for connectionsPerHost for # of threads that can block. Default is 5.
|
||||
If connectionsPerHost is 10, and threadsAllowedToBlockForConnectionMultiplier is 5,
|
||||
then 50 threads can block more than that and an exception will be thrown.
|
||||
]]></xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="max-wait-time" type="xsd:string">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
The max wait time of a blocking thread for a connection. Default is 12000 ms (2 minutes)
|
||||
]]></xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="connect-timeout" type="xsd:string">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
The connect timeout in milliseconds. 0 is default and infinite.
|
||||
]]></xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="socket-timeout" type="xsd:string">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
The socket timeout. 0 is default and infinite.
|
||||
]]></xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="socket-keep-alive" type="xsd:string">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
The keep alive flag, controls whether or not to have socket keep alive timeout. Defaults to false.
|
||||
]]></xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="auto-connect-retry" type="xsd:string">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
This controls whether or not on a connect, the system retries automatically. Default is false.
|
||||
]]></xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="max-auto-connect-retry-time" type="xsd:long">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
The maximum amount of time in millisecons to spend retrying to open connection to the same server. Default is 0, which means to use the default 15s if autoConnectRetry is on.
|
||||
]]></xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="write-number" type="xsd:string">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
This specifies the number of servers to wait for on the write operation, and exception raising behavior. The 'w' option to the getlasterror command. Defaults to 0.
|
||||
]]></xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="write-timeout" type="xsd:string">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
This controls timeout for write operations in milliseconds. The 'wtimeout' option to the getlasterror command. Defaults to 0 (indefinite). Greater than zero is number of milliseconds to wait.
|
||||
]]></xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="write-fsync" type="xsd:string">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
This controls whether or not to fsync. The 'fsync' option to the getlasterror command. Defaults to false.
|
||||
]]></xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="slave-ok" type="xsd:string">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
This controls if the driver is allowed to read from secondaries or slaves. Defaults to false.
|
||||
]]></xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
</xsd:complexType>
|
||||
|
||||
<xsd:group name="beanElementGroup">
|
||||
<xsd:choice>
|
||||
<xsd:element ref="beans:bean"/>
|
||||
<xsd:element ref="beans:ref"/>
|
||||
</xsd:choice>
|
||||
</xsd:group>
|
||||
|
||||
<xsd:complexType name="customConverterType">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
Element defining a custom converterr.
|
||||
]]></xsd:documentation>
|
||||
</xsd:annotation>
|
||||
<xsd:group ref="beanElementGroup" minOccurs="0" maxOccurs="1"/>
|
||||
<xsd:attribute name="ref" type="xsd:string">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation>
|
||||
A reference to a custom converter.
|
||||
</xsd:documentation>
|
||||
<xsd:appinfo>
|
||||
<tool:annotation kind="ref"/>
|
||||
</xsd:appinfo>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
</xsd:complexType>
|
||||
|
||||
<xsd:simpleType name="converterRef">
|
||||
<xsd:annotation>
|
||||
<xsd:appinfo>
|
||||
<tool:annotation kind="ref">
|
||||
<tool:assignable-to type="org.springframework.data.mongodb.core.convert.MongoConverter"/>
|
||||
</tool:annotation>
|
||||
</xsd:appinfo>
|
||||
</xsd:annotation>
|
||||
<xsd:union memberTypes="xsd:string"/>
|
||||
</xsd:simpleType>
|
||||
|
||||
<xsd:element name="template">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
Defines a MongoDbFactory for connecting to a specific database
|
||||
]]></xsd:documentation>
|
||||
</xsd:annotation>
|
||||
<xsd:complexType>
|
||||
<xsd:attribute name="id" type="xsd:string" use="optional">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
The name of the mongo definition (by default "mongoDbFactory").]]></xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="converter-ref" type="converterRef" use="optional">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
The reference to a Mongoconverter instance.
|
||||
]]>
|
||||
</xsd:documentation>
|
||||
<xsd:appinfo>
|
||||
<tool:annotation kind="ref">
|
||||
<tool:assignable-to type="org.springframework.data.mongodb.core.convert.MongoConverter"/>
|
||||
</tool:annotation>
|
||||
</xsd:appinfo>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="db-factory-ref" type="xsd:string"
|
||||
use="optional">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation>
|
||||
The reference to a DbFactory.
|
||||
</xsd:documentation>
|
||||
<xsd:appinfo>
|
||||
<tool:annotation kind="ref">
|
||||
<tool:assignable-to
|
||||
type="org.springframework.data.mongodb.MongoDbFactory" />
|
||||
</tool:annotation>
|
||||
</xsd:appinfo>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="write-concern">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation>
|
||||
The WriteConcern that will be the default value used when asking the MongoDbFactory for a DB object
|
||||
</xsd:documentation>
|
||||
</xsd:annotation>
|
||||
<xsd:simpleType>
|
||||
<xsd:union memberTypes="writeConcernEnumeration xsd:string"/>
|
||||
</xsd:simpleType>
|
||||
</xsd:attribute>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
|
||||
<xsd:element name="gridFsTemplate">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
Defines a MongoDbFactory for connecting to a specific database
|
||||
]]></xsd:documentation>
|
||||
</xsd:annotation>
|
||||
<xsd:complexType>
|
||||
<xsd:attribute name="id" type="xsd:string" use="optional">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
The name of the mongo definition (by default "mongoDbFactory").]]></xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="converter-ref" type="converterRef" use="optional">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
The reference to a Mongoconverter instance.
|
||||
]]>
|
||||
</xsd:documentation>
|
||||
<xsd:appinfo>
|
||||
<tool:annotation kind="ref">
|
||||
<tool:assignable-to type="org.springframework.data.mongodb.core.convert.MongoConverter"/>
|
||||
</tool:annotation>
|
||||
</xsd:appinfo>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="db-factory-ref" type="xsd:string" use="optional">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation>
|
||||
The reference to a DbFactory.
|
||||
</xsd:documentation>
|
||||
<xsd:appinfo>
|
||||
<tool:annotation kind="ref">
|
||||
<tool:assignable-to type="org.springframework.data.mongodb.MongoDbFactory" />
|
||||
</tool:annotation>
|
||||
</xsd:appinfo>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:schema>
|
||||
@@ -18,15 +18,9 @@ package org.springframework.data.mongodb.config;
|
||||
import static org.hamcrest.Matchers.*;
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.rules.ExpectedException;
|
||||
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
|
||||
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.data.mongodb.MongoDbFactory;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.data.mongodb.core.mapping.Document;
|
||||
import org.springframework.data.mongodb.core.mapping.MongoMappingContext;
|
||||
|
||||
import com.mongodb.Mongo;
|
||||
|
||||
@@ -37,9 +31,6 @@ import com.mongodb.Mongo;
|
||||
*/
|
||||
public class AbstractMongoConfigurationUnitTests {
|
||||
|
||||
@Rule
|
||||
public ExpectedException exception = ExpectedException.none();
|
||||
|
||||
/**
|
||||
* @see DATAMONGO-496
|
||||
*/
|
||||
@@ -72,31 +63,6 @@ public class AbstractMongoConfigurationUnitTests {
|
||||
assertScanningDisabled(" ");
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATAMONGO-569
|
||||
*/
|
||||
@Test
|
||||
public void containsMongoDbFactoryButNoMongoBean() {
|
||||
|
||||
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(SampleMongoConfiguration.class);
|
||||
|
||||
assertThat(context.getBean(MongoDbFactory.class), is(notNullValue()));
|
||||
|
||||
exception.expect(NoSuchBeanDefinitionException.class);
|
||||
context.getBean(Mongo.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void returnsUninitializedMappingContext() throws Exception {
|
||||
|
||||
SampleMongoConfiguration configuration = new SampleMongoConfiguration();
|
||||
MongoMappingContext context = configuration.mongoMappingContext();
|
||||
|
||||
assertThat(context.getPersistentEntities(), is(emptyIterable()));
|
||||
context.initialize();
|
||||
assertThat(context.getPersistentEntities(), is(not(emptyIterable())));
|
||||
}
|
||||
|
||||
private static void assertScanningDisabled(final String value) throws ClassNotFoundException {
|
||||
|
||||
AbstractMongoConfiguration configuration = new SampleMongoConfiguration() {
|
||||
@@ -110,7 +76,6 @@ public class AbstractMongoConfigurationUnitTests {
|
||||
assertThat(configuration.getInitialEntitySet(), hasSize(0));
|
||||
}
|
||||
|
||||
@Configuration
|
||||
static class SampleMongoConfiguration extends AbstractMongoConfiguration {
|
||||
|
||||
@Override
|
||||
@@ -118,6 +83,7 @@ public class AbstractMongoConfigurationUnitTests {
|
||||
return "database";
|
||||
}
|
||||
|
||||
@Bean
|
||||
@Override
|
||||
public Mongo mongo() throws Exception {
|
||||
return new Mongo();
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2011-2013 the original author or authors.
|
||||
* Copyright 2011-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.
|
||||
@@ -15,7 +15,7 @@
|
||||
*/
|
||||
package org.springframework.data.mongodb.config;
|
||||
|
||||
import static org.hamcrest.Matchers.*;
|
||||
import static org.hamcrest.CoreMatchers.*;
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import java.util.Collections;
|
||||
@@ -23,7 +23,6 @@ import java.util.Set;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.springframework.beans.factory.config.BeanDefinition;
|
||||
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
|
||||
import org.springframework.beans.factory.xml.XmlBeanDefinitionReader;
|
||||
import org.springframework.core.convert.TypeDescriptor;
|
||||
@@ -32,7 +31,6 @@ import org.springframework.core.convert.converter.GenericConverter;
|
||||
import org.springframework.core.io.ClassPathResource;
|
||||
import org.springframework.data.mongodb.core.convert.CustomConversions;
|
||||
import org.springframework.data.mongodb.core.mapping.Account;
|
||||
import org.springframework.data.mongodb.core.mapping.CamelCaseAbbreviatingFieldNamingStrategy;
|
||||
import org.springframework.data.mongodb.repository.Person;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@@ -69,20 +67,6 @@ public class MappingMongoConverterParserIntegrationTests {
|
||||
assertThat(conversions.hasCustomWriteTarget(Account.class), is(true));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATAMONGO-607
|
||||
*/
|
||||
@Test
|
||||
public void activatesAbbreviatingPropertiesCorrectly() {
|
||||
|
||||
BeanDefinition definition = factory.getBeanDefinition("abbreviatingConverter.mappingContext");
|
||||
Object value = definition.getPropertyValues().getPropertyValue("fieldNamingStrategy").getValue();
|
||||
|
||||
assertThat(value, is(instanceOf(BeanDefinition.class)));
|
||||
BeanDefinition strategy = (BeanDefinition) value;
|
||||
assertThat(strategy.getBeanClassName(), is(CamelCaseAbbreviatingFieldNamingStrategy.class.getName()));
|
||||
}
|
||||
|
||||
@Component
|
||||
public static class SampleConverter implements Converter<Person, DBObject> {
|
||||
public DBObject convert(Person source) {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2010-2013 the original author or authors.
|
||||
* Copyright 2010 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.
|
||||
@@ -13,6 +13,7 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.data.mongodb.config;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
@@ -25,23 +26,12 @@ import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.data.authentication.UserCredentials;
|
||||
import org.springframework.data.mongodb.MongoDbFactory;
|
||||
import org.springframework.data.mongodb.core.MongoFactoryBean;
|
||||
import org.springframework.data.mongodb.core.MongoOperations;
|
||||
import org.springframework.data.mongodb.core.convert.MongoConverter;
|
||||
import org.springframework.data.mongodb.gridfs.GridFsOperations;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
|
||||
import com.mongodb.Mongo;
|
||||
import com.mongodb.MongoOptions;
|
||||
import com.mongodb.WriteConcern;
|
||||
|
||||
/**
|
||||
* Integration tests for the MongoDB namespace.
|
||||
*
|
||||
* @author Mark Pollack
|
||||
* @author Oliver Gierke
|
||||
* @author Martin Baumgartner
|
||||
*/
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
@ContextConfiguration
|
||||
public class MongoNamespaceTests {
|
||||
@@ -68,7 +58,7 @@ public class MongoNamespaceTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSecondMongoDbFactory() {
|
||||
public void testSecondMongoDbFactory() throws Exception {
|
||||
assertTrue(ctx.containsBean("secondMongoDbFactory"));
|
||||
MongoDbFactory dbf = (MongoDbFactory) ctx.getBean("secondMongoDbFactory");
|
||||
Mongo mongo = (Mongo) getField(dbf, "mongo");
|
||||
@@ -78,58 +68,6 @@ public class MongoNamespaceTests {
|
||||
assertEquals("database", getField(dbf, "databaseName"));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATAMONGO-140
|
||||
*/
|
||||
@Test
|
||||
public void testMongoTemplateFactory() {
|
||||
assertTrue(ctx.containsBean("mongoTemplate"));
|
||||
MongoOperations operations = (MongoOperations) ctx.getBean("mongoTemplate");
|
||||
MongoDbFactory dbf = (MongoDbFactory) getField(operations, "mongoDbFactory");
|
||||
assertEquals("database", getField(dbf, "databaseName"));
|
||||
MongoConverter converter = (MongoConverter) getField(operations, "mongoConverter");
|
||||
assertNotNull(converter);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATAMONGO-140
|
||||
*/
|
||||
@Test
|
||||
public void testSecondMongoTemplateFactory() {
|
||||
assertTrue(ctx.containsBean("anotherMongoTemplate"));
|
||||
MongoOperations operations = (MongoOperations) ctx.getBean("anotherMongoTemplate");
|
||||
MongoDbFactory dbf = (MongoDbFactory) getField(operations, "mongoDbFactory");
|
||||
assertEquals("database", getField(dbf, "databaseName"));
|
||||
WriteConcern writeConcern = (WriteConcern) getField(operations, "writeConcern");
|
||||
assertEquals(WriteConcern.SAFE, writeConcern);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATAMONGO-628
|
||||
*/
|
||||
@Test
|
||||
public void testGridFsTemplateFactory() {
|
||||
assertTrue(ctx.containsBean("gridFsTemplate"));
|
||||
GridFsOperations operations = (GridFsOperations) ctx.getBean("gridFsTemplate");
|
||||
MongoDbFactory dbf = (MongoDbFactory) getField(operations, "dbFactory");
|
||||
assertEquals("database", getField(dbf, "databaseName"));
|
||||
MongoConverter converter = (MongoConverter) getField(operations, "converter");
|
||||
assertNotNull(converter);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATAMONGO-628
|
||||
*/
|
||||
@Test
|
||||
public void testSecondGridFsTemplateFactory() {
|
||||
assertTrue(ctx.containsBean("antoherGridFsTemplate"));
|
||||
GridFsOperations operations = (GridFsOperations) ctx.getBean("antoherGridFsTemplate");
|
||||
MongoDbFactory dbf = (MongoDbFactory) getField(operations, "dbFactory");
|
||||
assertEquals("database", getField(dbf, "databaseName"));
|
||||
MongoConverter converter = (MongoConverter) getField(operations, "converter");
|
||||
assertNotNull(converter);
|
||||
}
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("deprecation")
|
||||
public void testMongoSingletonWithPropertyPlaceHolders() throws Exception {
|
||||
|
||||
@@ -50,10 +50,9 @@ import org.springframework.dao.OptimisticLockingFailureException;
|
||||
import org.springframework.data.annotation.Id;
|
||||
import org.springframework.data.annotation.PersistenceConstructor;
|
||||
import org.springframework.data.annotation.Version;
|
||||
import org.springframework.data.domain.Sort;
|
||||
import org.springframework.data.domain.Sort.Direction;
|
||||
import org.springframework.data.mapping.model.MappingException;
|
||||
import org.springframework.data.mongodb.InvalidMongoDbApiUsageException;
|
||||
import org.springframework.data.mongodb.MongoDataIntegrityViolationException;
|
||||
import org.springframework.data.mongodb.MongoDbFactory;
|
||||
import org.springframework.data.mongodb.core.convert.CustomConversions;
|
||||
import org.springframework.data.mongodb.core.convert.MappingMongoConverter;
|
||||
@@ -64,6 +63,7 @@ import org.springframework.data.mongodb.core.index.IndexInfo;
|
||||
import org.springframework.data.mongodb.core.mapping.MongoMappingContext;
|
||||
import org.springframework.data.mongodb.core.query.BasicQuery;
|
||||
import org.springframework.data.mongodb.core.query.Criteria;
|
||||
import org.springframework.data.mongodb.core.query.Order;
|
||||
import org.springframework.data.mongodb.core.query.Query;
|
||||
import org.springframework.data.mongodb.core.query.Update;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
@@ -236,7 +236,7 @@ public class MongoTemplateTests {
|
||||
|
||||
MongoTemplate template = new MongoTemplate(factory);
|
||||
template.setWriteResultChecking(WriteResultChecking.EXCEPTION);
|
||||
template.indexOps(Person.class).ensureIndex(new Index().on("firstName", Direction.DESC).unique());
|
||||
template.indexOps(Person.class).ensureIndex(new Index().on("firstName", Order.DESCENDING).unique());
|
||||
|
||||
Person person = new Person(new ObjectId(), "Amol");
|
||||
person.setAge(28);
|
||||
@@ -293,7 +293,7 @@ public class MongoTemplateTests {
|
||||
p2.setAge(40);
|
||||
template.insert(p2);
|
||||
|
||||
template.indexOps(Person.class).ensureIndex(new Index().on("age", Direction.DESC).unique(Duplicates.DROP));
|
||||
template.indexOps(Person.class).ensureIndex(new Index().on("age", Order.DESCENDING).unique(Duplicates.DROP));
|
||||
|
||||
DBCollection coll = template.getCollection(template.getCollectionName(Person.class));
|
||||
List<DBObject> indexInfo = coll.getIndexInfo();
|
||||
@@ -323,7 +323,7 @@ public class MongoTemplateTests {
|
||||
List<IndexField> indexFields = ii.getIndexFields();
|
||||
IndexField field = indexFields.get(0);
|
||||
|
||||
assertThat(field, is(IndexField.create("age", Direction.DESC)));
|
||||
assertThat(field, is(IndexField.create("age", Order.DESCENDING)));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -950,7 +950,7 @@ public class MongoTemplateTests {
|
||||
|
||||
// test query with a sort
|
||||
Query q2 = new Query(Criteria.where("age").gt(10));
|
||||
q2.with(new Sort(Direction.DESC, "age"));
|
||||
q2.sort().on("age", Order.DESCENDING);
|
||||
PersonWithAList p5 = template.findOne(q2, PersonWithAList.class);
|
||||
assertThat(p5.getFirstName(), is("Mark"));
|
||||
}
|
||||
@@ -1597,34 +1597,6 @@ public class MongoTemplateTests {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATAMONGO-679
|
||||
*/
|
||||
@Test
|
||||
public void savesJsonStringCorrectly() {
|
||||
|
||||
DBObject dbObject = new BasicDBObject().append("first", "first").append("second", "second");
|
||||
|
||||
template.save(dbObject.toString(), "collection");
|
||||
|
||||
List<DBObject> result = template.findAll(DBObject.class, "collection");
|
||||
assertThat(result.size(), is(1));
|
||||
assertThat(result.get(0).containsField("first"), is(true));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void executesExistsCorrectly() {
|
||||
|
||||
Sample sample = new Sample();
|
||||
template.save(sample);
|
||||
|
||||
Query query = query(where("id").is(sample.id));
|
||||
|
||||
assertThat(template.exists(query, Sample.class), is(true));
|
||||
assertThat(template.exists(query(where("_id").is(sample.id)), template.getCollectionName(Sample.class)), is(true));
|
||||
assertThat(template.exists(query, Sample.class, template.getCollectionName(Sample.class)), is(true));
|
||||
}
|
||||
|
||||
static class MyId {
|
||||
|
||||
String first;
|
||||
|
||||
@@ -45,6 +45,8 @@ import org.mockito.Mock;
|
||||
import org.mockito.runners.MockitoJUnitRunner;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.event.ContextRefreshedEvent;
|
||||
import org.springframework.core.convert.converter.Converter;
|
||||
import org.springframework.data.annotation.Id;
|
||||
import org.springframework.data.annotation.PersistenceConstructor;
|
||||
import org.springframework.data.annotation.TypeAlias;
|
||||
@@ -70,7 +72,6 @@ import com.mongodb.util.JSON;
|
||||
* Unit tests for {@link MappingMongoConverter}.
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
* @author Patrik Wasik
|
||||
*/
|
||||
@RunWith(MockitoJUnitRunner.class)
|
||||
public class MappingMongoConverterUnitTests {
|
||||
@@ -87,7 +88,7 @@ public class MappingMongoConverterUnitTests {
|
||||
|
||||
mappingContext = new MongoMappingContext();
|
||||
mappingContext.setApplicationContext(context);
|
||||
mappingContext.afterPropertiesSet();
|
||||
mappingContext.onApplicationEvent(new ContextRefreshedEvent(context));
|
||||
|
||||
converter = new MappingMongoConverter(factory, mappingContext);
|
||||
converter.afterPropertiesSet();
|
||||
@@ -1320,53 +1321,6 @@ public class MappingMongoConverterUnitTests {
|
||||
converter.read(ObjectContainer.class, input);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATAMONGO-657
|
||||
*/
|
||||
@Test
|
||||
public void convertDocumentWithMapDBRef() {
|
||||
|
||||
MapDBRef mapDBRef = new MapDBRef();
|
||||
|
||||
MapDBRefVal val = new MapDBRefVal();
|
||||
val.id = BigInteger.ONE;
|
||||
|
||||
Map<String, MapDBRefVal> mapVal = new HashMap<String, MapDBRefVal>();
|
||||
mapVal.put("test", val);
|
||||
|
||||
mapDBRef.map = mapVal;
|
||||
|
||||
BasicDBObject dbObject = new BasicDBObject();
|
||||
converter.write(mapDBRef, dbObject);
|
||||
|
||||
DBObject map = (DBObject) dbObject.get("map");
|
||||
|
||||
assertThat(map.get("test"), instanceOf(DBRef.class));
|
||||
|
||||
DBObject mapValDBObject = new BasicDBObject();
|
||||
mapValDBObject.put("_id", BigInteger.ONE);
|
||||
|
||||
DBRef dbRef = mock(DBRef.class);
|
||||
when(dbRef.fetch()).thenReturn(mapValDBObject);
|
||||
|
||||
((DBObject) dbObject.get("map")).put("test", dbRef);
|
||||
|
||||
MapDBRef read = converter.read(MapDBRef.class, dbObject);
|
||||
|
||||
assertThat(read.map.get("test").id, is(BigInteger.ONE));
|
||||
}
|
||||
|
||||
@Document
|
||||
class MapDBRef {
|
||||
@org.springframework.data.mongodb.core.mapping.DBRef
|
||||
Map<String, MapDBRefVal> map;
|
||||
}
|
||||
|
||||
@Document
|
||||
class MapDBRefVal {
|
||||
BigInteger id;
|
||||
}
|
||||
|
||||
static class GenericType<T> {
|
||||
T content;
|
||||
}
|
||||
@@ -1591,4 +1545,18 @@ public class MappingMongoConverterUnitTests {
|
||||
return m_property;
|
||||
}
|
||||
}
|
||||
|
||||
private class LocalDateToDateConverter implements Converter<LocalDate, Date> {
|
||||
|
||||
public Date convert(LocalDate source) {
|
||||
return source.toDateMidnight().toDate();
|
||||
}
|
||||
}
|
||||
|
||||
private class DateToLocalDateConverter implements Converter<Date, LocalDate> {
|
||||
|
||||
public LocalDate convert(Date source) {
|
||||
return new LocalDate(source.getTime());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,7 +25,6 @@ import java.math.BigInteger;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.bson.types.ObjectId;
|
||||
import org.junit.Before;
|
||||
@@ -54,7 +53,6 @@ import com.mongodb.QueryBuilder;
|
||||
* Unit tests for {@link QueryMapper}.
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
* @author Patryk Wasik
|
||||
*/
|
||||
@RunWith(MockitoJUnitRunner.class)
|
||||
public class QueryMapperUnitTests {
|
||||
@@ -365,35 +363,6 @@ public class QueryMapperUnitTests {
|
||||
assertThat(object.containsField("_id"), is(false));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATAMONGO-677
|
||||
*/
|
||||
@Test
|
||||
public void handleMapWithDBRefCorrectly() {
|
||||
|
||||
DBObject mapDbObject = new BasicDBObject();
|
||||
mapDbObject.put("test", new com.mongodb.DBRef(null, "test", "test"));
|
||||
DBObject dbObject = new BasicDBObject();
|
||||
dbObject.put("mapWithDBRef", mapDbObject);
|
||||
|
||||
DBObject mapped = mapper.getMappedObject(dbObject, context.getPersistentEntity(WithMapDBRef.class));
|
||||
|
||||
assertThat(mapped.containsField("mapWithDBRef"), is(true));
|
||||
assertThat(mapped.get("mapWithDBRef"), instanceOf(BasicDBObject.class));
|
||||
assertThat(((BasicDBObject) mapped.get("mapWithDBRef")).containsField("test"), is(true));
|
||||
assertThat(((BasicDBObject) mapped.get("mapWithDBRef")).get("test"), instanceOf(com.mongodb.DBRef.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void convertsUnderscoreIdValueWithoutMetadata() {
|
||||
|
||||
DBObject dbObject = new BasicDBObject().append("_id", new ObjectId().toString());
|
||||
|
||||
DBObject mapped = mapper.getMappedObject(dbObject, null);
|
||||
assertThat(mapped.containsField("_id"), is(true));
|
||||
assertThat(mapped.get("_id"), is(instanceOf(ObjectId.class)));
|
||||
}
|
||||
|
||||
class IdWrapper {
|
||||
Object id;
|
||||
}
|
||||
@@ -446,10 +415,4 @@ public class QueryMapperUnitTests {
|
||||
|
||||
WithDBRef withDbRef;
|
||||
}
|
||||
|
||||
class WithMapDBRef {
|
||||
|
||||
@DBRef
|
||||
Map<String, Sample> mapWithDBRef;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -33,7 +33,6 @@ import org.junit.Test;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
|
||||
import org.springframework.dao.DataAccessException;
|
||||
import org.springframework.data.domain.Sort.Direction;
|
||||
import org.springframework.data.mongodb.core.CollectionCallback;
|
||||
import org.springframework.data.mongodb.core.IndexOperations;
|
||||
import org.springframework.data.mongodb.core.MongoTemplate;
|
||||
@@ -42,6 +41,7 @@ import org.springframework.data.mongodb.core.index.GeospatialIndex;
|
||||
import org.springframework.data.mongodb.core.index.IndexField;
|
||||
import org.springframework.data.mongodb.core.index.IndexInfo;
|
||||
import org.springframework.data.mongodb.core.query.NearQuery;
|
||||
import org.springframework.data.mongodb.core.query.Order;
|
||||
import org.springframework.data.mongodb.core.query.Query;
|
||||
import org.springframework.data.mongodb.monitor.ServerInfo;
|
||||
import org.springframework.expression.ExpressionParser;
|
||||
@@ -58,7 +58,6 @@ import com.mongodb.WriteConcern;
|
||||
* Modified from https://github.com/deftlabs/mongo-java-geospatial-example
|
||||
*
|
||||
* @author Mark Pollack
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
public class GeoSpatialTests {
|
||||
|
||||
@@ -212,7 +211,7 @@ public class GeoSpatialTests {
|
||||
|
||||
List<IndexField> fields = indexInfo.get(0).getIndexFields();
|
||||
assertThat(fields.size(), is(1));
|
||||
assertThat(fields, hasItem(IndexField.create("_id", Direction.ASC)));
|
||||
assertThat(fields, hasItem(IndexField.create("_id", Order.ASCENDING)));
|
||||
|
||||
fields = indexInfo.get(1).getIndexFields();
|
||||
assertThat(fields.size(), is(1));
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2013 the original author or authors.
|
||||
* 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.
|
||||
@@ -19,7 +19,6 @@ import static org.hamcrest.CoreMatchers.*;
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.springframework.data.domain.Sort.Direction;
|
||||
import org.springframework.data.mongodb.core.query.Order;
|
||||
|
||||
/**
|
||||
@@ -27,16 +26,14 @@ import org.springframework.data.mongodb.core.query.Order;
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
@SuppressWarnings("deprecation")
|
||||
public class IndexFieldUnitTests {
|
||||
|
||||
@Test
|
||||
public void createsPlainIndexFieldCorrectly() {
|
||||
|
||||
IndexField field = IndexField.create("foo", Direction.ASC);
|
||||
IndexField field = IndexField.create("foo", Order.ASCENDING);
|
||||
|
||||
assertThat(field.getKey(), is("foo"));
|
||||
assertThat(field.getDirection(), is(Direction.ASC));
|
||||
assertThat(field.getOrder(), is(Order.ASCENDING));
|
||||
assertThat(field.isGeo(), is(false));
|
||||
}
|
||||
@@ -47,15 +44,15 @@ public class IndexFieldUnitTests {
|
||||
IndexField field = IndexField.geo("foo");
|
||||
|
||||
assertThat(field.getKey(), is("foo"));
|
||||
assertThat(field.getDirection(), is(nullValue()));
|
||||
assertThat(field.getOrder(), is(nullValue()));
|
||||
assertThat(field.isGeo(), is(true));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void correctEqualsForPlainFields() {
|
||||
|
||||
IndexField first = IndexField.create("foo", Direction.ASC);
|
||||
IndexField second = IndexField.create("foo", Direction.ASC);
|
||||
IndexField first = IndexField.create("foo", Order.ASCENDING);
|
||||
IndexField second = IndexField.create("foo", Order.ASCENDING);
|
||||
|
||||
assertThat(first, is(second));
|
||||
assertThat(second, is(first));
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2013 the original author or authors.
|
||||
* 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.
|
||||
@@ -21,7 +21,7 @@ import static org.junit.Assert.*;
|
||||
import java.util.Arrays;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.springframework.data.domain.Sort.Direction;
|
||||
import org.springframework.data.mongodb.core.query.Order;
|
||||
|
||||
/**
|
||||
* Unit tests for {@link IndexInfo}.
|
||||
@@ -33,8 +33,8 @@ public class IndexInfoUnitTests {
|
||||
@Test
|
||||
public void isIndexForFieldsCorrectly() {
|
||||
|
||||
IndexField fooField = IndexField.create("foo", Direction.ASC);
|
||||
IndexField barField = IndexField.create("bar", Direction.DESC);
|
||||
IndexField fooField = IndexField.create("foo", Order.ASCENDING);
|
||||
IndexField barField = IndexField.create("bar", Order.DESCENDING);
|
||||
|
||||
IndexInfo info = new IndexInfo(Arrays.asList(fooField, barField), "myIndex", false, false, false);
|
||||
assertThat(info.isIndexForFields(Arrays.asList("foo", "bar")), is(true));
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2013 the original author or authors.
|
||||
* 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.
|
||||
@@ -15,7 +15,7 @@
|
||||
*/
|
||||
package org.springframework.data.mongodb.core.index;
|
||||
|
||||
import static org.hamcrest.Matchers.*;
|
||||
import static org.hamcrest.CoreMatchers.*;
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import java.util.Collections;
|
||||
@@ -38,7 +38,6 @@ import com.mongodb.DBObject;
|
||||
* Unit tests for {@link MongoPersistentEntityIndexCreator}.
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
* @author Philipp Schneider
|
||||
*/
|
||||
@RunWith(MockitoJUnitRunner.class)
|
||||
public class MongoPersistentEntityIndexCreatorUnitTests {
|
||||
@@ -51,20 +50,25 @@ public class MongoPersistentEntityIndexCreatorUnitTests {
|
||||
@Test
|
||||
public void buildsIndexDefinitionUsingFieldName() {
|
||||
|
||||
MongoMappingContext mappingContext = prepareMappingContext(Person.class);
|
||||
MongoMappingContext mappingContext = new MongoMappingContext();
|
||||
mappingContext.setInitialEntitySet(Collections.singleton(Person.class));
|
||||
mappingContext.initialize();
|
||||
|
||||
DummyMongoPersistentEntityIndexCreator creator = new DummyMongoPersistentEntityIndexCreator(mappingContext, factory);
|
||||
|
||||
assertThat(creator.indexDefinition, is(notNullValue()));
|
||||
assertThat(creator.indexDefinition.keySet(), hasItem("fieldname"));
|
||||
assertThat(creator.name, is("indexName"));
|
||||
assertThat(creator.background, is(false));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void doesNotCreateIndexForEntityComingFromDifferentMappingContext() {
|
||||
|
||||
MongoMappingContext mappingContext = new MongoMappingContext();
|
||||
MongoMappingContext personMappingContext = prepareMappingContext(Person.class);
|
||||
|
||||
MongoMappingContext personMappingContext = new MongoMappingContext();
|
||||
personMappingContext.setInitialEntitySet(Collections.singleton(Person.class));
|
||||
personMappingContext.initialize();
|
||||
|
||||
DummyMongoPersistentEntityIndexCreator creator = new DummyMongoPersistentEntityIndexCreator(mappingContext, factory);
|
||||
|
||||
@@ -91,49 +95,17 @@ public class MongoPersistentEntityIndexCreatorUnitTests {
|
||||
assertThat(creator.isIndexCreatorFor(new MongoMappingContext()), is(false));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATAMONGO-554
|
||||
*/
|
||||
@Test
|
||||
public void triggersBackgroundIndexingIfConfigured() {
|
||||
|
||||
MongoMappingContext mappingContext = prepareMappingContext(AnotherPerson.class);
|
||||
DummyMongoPersistentEntityIndexCreator creator = new DummyMongoPersistentEntityIndexCreator(mappingContext, factory);
|
||||
|
||||
assertThat(creator.indexDefinition, is(notNullValue()));
|
||||
assertThat(creator.indexDefinition.keySet(), hasItem("lastname"));
|
||||
assertThat(creator.name, is("lastname"));
|
||||
assertThat(creator.background, is(true));
|
||||
}
|
||||
|
||||
private static MongoMappingContext prepareMappingContext(Class<?> type) {
|
||||
|
||||
MongoMappingContext mappingContext = new MongoMappingContext();
|
||||
mappingContext.setInitialEntitySet(Collections.singleton(type));
|
||||
mappingContext.initialize();
|
||||
|
||||
return mappingContext;
|
||||
}
|
||||
|
||||
static class Person {
|
||||
|
||||
@Indexed(name = "indexName")
|
||||
@Field("fieldname")
|
||||
String field;
|
||||
|
||||
}
|
||||
|
||||
static class AnotherPerson {
|
||||
|
||||
@Indexed(background = true)
|
||||
String lastname;
|
||||
}
|
||||
|
||||
static class DummyMongoPersistentEntityIndexCreator extends MongoPersistentEntityIndexCreator {
|
||||
|
||||
DBObject indexDefinition;
|
||||
String name;
|
||||
boolean background;
|
||||
|
||||
public DummyMongoPersistentEntityIndexCreator(MongoMappingContext mappingContext, MongoDbFactory mongoDbFactory) {
|
||||
super(mappingContext, mongoDbFactory);
|
||||
@@ -141,11 +113,10 @@ public class MongoPersistentEntityIndexCreatorUnitTests {
|
||||
|
||||
@Override
|
||||
protected void ensureIndex(String collection, String name, DBObject indexDefinition, boolean unique,
|
||||
boolean dropDups, boolean sparse, boolean background) {
|
||||
boolean dropDups, boolean sparse) {
|
||||
|
||||
this.name = name;
|
||||
this.indexDefinition = indexDefinition;
|
||||
this.background = background;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2011-2013 by the original author(s).
|
||||
* Copyright (c) 2011 by the original author(s).
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -15,9 +15,9 @@
|
||||
*/
|
||||
package org.springframework.data.mongodb.core.mapping;
|
||||
|
||||
import static org.mockito.Mockito.*;
|
||||
import static org.hamcrest.CoreMatchers.*;
|
||||
import static org.junit.Assert.*;
|
||||
import static org.mockito.Mockito.*;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2011-2013 by the original author(s).
|
||||
* Copyright (c) 2011 by the original author(s).
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -19,14 +19,10 @@ import static org.hamcrest.CoreMatchers.*;
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.Locale;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.rules.ExpectedException;
|
||||
import org.springframework.data.annotation.Id;
|
||||
import org.springframework.data.mapping.model.MappingException;
|
||||
import org.springframework.data.mapping.model.SimpleTypeHolder;
|
||||
import org.springframework.data.util.ClassTypeInformation;
|
||||
import org.springframework.util.ReflectionUtils;
|
||||
@@ -40,9 +36,6 @@ public class BasicMongoPersistentPropertyUnitTests {
|
||||
|
||||
MongoPersistentEntity<Person> entity;
|
||||
|
||||
@Rule
|
||||
public ExpectedException exception = ExpectedException.none();
|
||||
|
||||
@Before
|
||||
public void setup() {
|
||||
entity = new BasicMongoPersistentEntity<Person>(ClassTypeInformation.from(Person.class));
|
||||
@@ -85,45 +78,8 @@ public class BasicMongoPersistentPropertyUnitTests {
|
||||
assertThat(property.usePropertyAccess(), is(true));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATAMONGO-607
|
||||
*/
|
||||
@Test
|
||||
public void usesCustomFieldNamingStrategyByDefault() throws Exception {
|
||||
|
||||
Field field = ReflectionUtils.findField(Person.class, "lastname");
|
||||
|
||||
MongoPersistentProperty property = new BasicMongoPersistentProperty(field, null, entity, new SimpleTypeHolder(),
|
||||
UppercaseFieldNamingStrategy.INSTANCE);
|
||||
assertThat(property.getFieldName(), is("LASTNAME"));
|
||||
|
||||
field = ReflectionUtils.findField(Person.class, "firstname");
|
||||
|
||||
property = new BasicMongoPersistentProperty(field, null, entity, new SimpleTypeHolder(),
|
||||
UppercaseFieldNamingStrategy.INSTANCE);
|
||||
assertThat(property.getFieldName(), is("foo"));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATAMONGO-607
|
||||
*/
|
||||
@Test
|
||||
public void rejectsInvalidValueReturnedByFieldNamingStrategy() {
|
||||
|
||||
Field field = ReflectionUtils.findField(Person.class, "lastname");
|
||||
MongoPersistentProperty property = new BasicMongoPersistentProperty(field, null, entity, new SimpleTypeHolder(),
|
||||
InvalidFieldNamingStrategy.INSTANCE);
|
||||
|
||||
exception.expect(MappingException.class);
|
||||
exception.expectMessage(InvalidFieldNamingStrategy.class.getName());
|
||||
exception.expectMessage(property.toString());
|
||||
|
||||
property.getFieldName();
|
||||
}
|
||||
|
||||
private MongoPersistentProperty getPropertyFor(Field field) {
|
||||
return new BasicMongoPersistentProperty(field, null, entity, new SimpleTypeHolder(),
|
||||
PropertyNameFieldNamingStrategy.INSTANCE);
|
||||
return new BasicMongoPersistentProperty(field, null, entity, new SimpleTypeHolder());
|
||||
}
|
||||
|
||||
class Person {
|
||||
@@ -138,22 +94,4 @@ public class BasicMongoPersistentPropertyUnitTests {
|
||||
@org.springframework.data.mongodb.core.mapping.Field(order = -20)
|
||||
String ssn;
|
||||
}
|
||||
|
||||
enum UppercaseFieldNamingStrategy implements FieldNamingStrategy {
|
||||
|
||||
INSTANCE;
|
||||
|
||||
public String getFieldName(MongoPersistentProperty property) {
|
||||
return property.getName().toUpperCase(Locale.US);
|
||||
}
|
||||
}
|
||||
|
||||
enum InvalidFieldNamingStrategy implements FieldNamingStrategy {
|
||||
|
||||
INSTANCE;
|
||||
|
||||
public String getFieldName(MongoPersistentProperty property) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,51 +0,0 @@
|
||||
/*
|
||||
* Copyright 2013 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.mapping;
|
||||
|
||||
import static org.hamcrest.CoreMatchers.*;
|
||||
import static org.junit.Assert.*;
|
||||
import static org.mockito.Mockito.*;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.runners.MockitoJUnitRunner;
|
||||
|
||||
/**
|
||||
* Unit tests for {@link CamelCaseAbbreviatingFieldNamingStrategy}.
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
@RunWith(MockitoJUnitRunner.class)
|
||||
public class CamelCaseAbbreviatingFieldNamingStrategyUnitTests {
|
||||
|
||||
FieldNamingStrategy strategy = new CamelCaseAbbreviatingFieldNamingStrategy();
|
||||
|
||||
@Mock
|
||||
MongoPersistentProperty property;
|
||||
|
||||
@Test
|
||||
public void foo() {
|
||||
assertFieldNameForPropertyName("fooBar", "fb");
|
||||
assertFieldNameForPropertyName("fooBARFooBar", "fbfb");
|
||||
}
|
||||
|
||||
private void assertFieldNameForPropertyName(String propertyName, String fieldName) {
|
||||
|
||||
when(property.getName()).thenReturn(propertyName);
|
||||
assertThat(strategy.getFieldName(property), is(fieldName));
|
||||
}
|
||||
}
|
||||
@@ -1,11 +1,11 @@
|
||||
/*
|
||||
* Copyright 2011-2013 the original author or authors.
|
||||
* Copyright (c) 2011 by the original author(s).
|
||||
*
|
||||
* 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,
|
||||
@@ -13,18 +13,21 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.data.mongodb.core.mapping;
|
||||
|
||||
import org.springframework.data.annotation.Id;
|
||||
import org.springframework.data.mongodb.core.index.Indexed;
|
||||
import org.springframework.data.mongodb.core.mapping.Document;
|
||||
|
||||
/**
|
||||
* @author Jon Brisbin
|
||||
* @author Jon Brisbin <jbrisbin@vmware.com>
|
||||
*/
|
||||
@Document(collection = "foobar")
|
||||
public class CustomCollectionWithIndex {
|
||||
|
||||
@Id
|
||||
@SuppressWarnings("unused")
|
||||
private String id;
|
||||
@Indexed
|
||||
private String name;
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
/*
|
||||
* Copyright 2011-2013 the original author or authors.
|
||||
* Copyright (c) 2011 by the original author(s).
|
||||
*
|
||||
* 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,
|
||||
@@ -13,18 +13,21 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.data.mongodb.core.mapping;
|
||||
|
||||
import org.springframework.data.annotation.Id;
|
||||
import org.springframework.data.mongodb.core.index.Indexed;
|
||||
import org.springframework.data.mongodb.core.mapping.Document;
|
||||
|
||||
/**
|
||||
* @author Jon Brisbin
|
||||
* @author Jon Brisbin <jbrisbin@vmware.com>
|
||||
*/
|
||||
@Document
|
||||
public class DetectedCollectionWithIndex {
|
||||
|
||||
@Id
|
||||
@SuppressWarnings("unused")
|
||||
private String id;
|
||||
@Indexed
|
||||
private String name;
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
/*
|
||||
* Copyright 2011-2013 the original author or authors.
|
||||
* Copyright (c) 2011 by the original author(s).
|
||||
*
|
||||
* 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,
|
||||
@@ -13,6 +13,7 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.data.mongodb.core.mapping;
|
||||
|
||||
import static org.hamcrest.Matchers.*;
|
||||
@@ -36,15 +37,14 @@ import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.support.ClassPathXmlApplicationContext;
|
||||
import org.springframework.dao.DataAccessException;
|
||||
import org.springframework.data.annotation.Id;
|
||||
import org.springframework.data.domain.Sort;
|
||||
import org.springframework.data.domain.Sort.Direction;
|
||||
import org.springframework.data.mapping.context.MappingContext;
|
||||
import org.springframework.data.mongodb.MongoCollectionUtils;
|
||||
import org.springframework.data.mongodb.core.CollectionCallback;
|
||||
import org.springframework.data.mongodb.core.MongoDbUtils;
|
||||
import org.springframework.data.mongodb.core.MongoTemplate;
|
||||
import org.springframework.data.mongodb.core.query.Criteria;
|
||||
import org.springframework.data.mongodb.core.query.Order;
|
||||
import org.springframework.data.mongodb.core.query.Query;
|
||||
import org.springframework.test.util.ReflectionTestUtils;
|
||||
|
||||
import com.mongodb.DB;
|
||||
import com.mongodb.DBCollection;
|
||||
@@ -53,8 +53,7 @@ import com.mongodb.Mongo;
|
||||
import com.mongodb.MongoException;
|
||||
|
||||
/**
|
||||
* @author Jon Brisbin
|
||||
* @author Oliver Gierke
|
||||
* @author Jon Brisbin <jbrisbin@vmware.com>
|
||||
*/
|
||||
public class MappingTests {
|
||||
|
||||
@@ -79,7 +78,7 @@ public class MappingTests {
|
||||
ApplicationContext applicationContext;
|
||||
Mongo mongo;
|
||||
MongoTemplate template;
|
||||
MappingContext<? extends MongoPersistentEntity<?>, MongoPersistentProperty> mappingContext;
|
||||
MongoMappingContext mappingContext;
|
||||
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
@@ -90,7 +89,7 @@ public class MappingTests {
|
||||
}
|
||||
applicationContext = new ClassPathXmlApplicationContext("/mapping.xml");
|
||||
template = applicationContext.getBean(MongoTemplate.class);
|
||||
mappingContext = template.getConverter().getMappingContext();
|
||||
mappingContext = (MongoMappingContext) ReflectionTestUtils.getField(template, "mappingContext");
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -465,7 +464,7 @@ public class MappingTests {
|
||||
template.insert(p4);
|
||||
|
||||
Query q = query(where("id").in("1", "2"));
|
||||
q.with(new Sort(Direction.ASC, "id"));
|
||||
q.sort().on("id", Order.ASCENDING);
|
||||
List<PersonPojoStringId> people = template.find(q, PersonPojoStringId.class);
|
||||
assertEquals(2, people.size());
|
||||
|
||||
|
||||
@@ -18,20 +18,20 @@ package org.springframework.data.mongodb.core.mapping;
|
||||
import static org.hamcrest.CoreMatchers.*;
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.AbstractMap;
|
||||
import java.util.Collections;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.rules.ExpectedException;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.runners.MockitoJUnitRunner;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.data.annotation.Id;
|
||||
import org.springframework.data.mapping.context.AbstractMappingContext;
|
||||
import org.springframework.data.mapping.model.MappingException;
|
||||
import org.springframework.util.ReflectionUtils;
|
||||
|
||||
import com.mongodb.DBRef;
|
||||
|
||||
@@ -46,9 +46,6 @@ public class MongoMappingContextUnitTests {
|
||||
@Mock
|
||||
ApplicationContext applicationContext;
|
||||
|
||||
@Rule
|
||||
public ExpectedException exception = ExpectedException.none();
|
||||
|
||||
@Test
|
||||
public void addsSelfReferencingPersistentEntityCorrectly() throws Exception {
|
||||
|
||||
@@ -72,6 +69,17 @@ public class MongoMappingContextUnitTests {
|
||||
assertThat(context.getPersistentEntity(DBRef.class), is(nullValue()));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void populatesAbstractMappingContextsApplicationCorrectly() {
|
||||
|
||||
MongoMappingContext context = new MongoMappingContext();
|
||||
context.setApplicationContext(applicationContext);
|
||||
|
||||
Field field = ReflectionUtils.findField(AbstractMappingContext.class, "applicationContext");
|
||||
ReflectionUtils.makeAccessible(field);
|
||||
assertThat(ReflectionUtils.getField(field, context), is(notNullValue()));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATAMONGO-638
|
||||
*/
|
||||
@@ -82,41 +90,6 @@ public class MongoMappingContextUnitTests {
|
||||
assertThat(context.getPersistentEntity(AbstractMap.class), is(nullValue()));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATAMONGO-607
|
||||
*/
|
||||
@Test
|
||||
public void populatesPersistentPropertyWithCustomFieldNamingStrategy() {
|
||||
|
||||
MongoMappingContext context = new MongoMappingContext();
|
||||
context.setApplicationContext(applicationContext);
|
||||
context.setFieldNamingStrategy(new FieldNamingStrategy() {
|
||||
|
||||
public String getFieldName(MongoPersistentProperty property) {
|
||||
return property.getName().toUpperCase(Locale.US);
|
||||
}
|
||||
});
|
||||
|
||||
MongoPersistentEntity<?> entity = context.getPersistentEntity(Person.class);
|
||||
assertThat(entity.getPersistentProperty("firstname").getFieldName(), is("FIRSTNAME"));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATAMONGO-607
|
||||
*/
|
||||
@Test
|
||||
public void rejectsClassWithAmbiguousFieldMappings() {
|
||||
|
||||
exception.expect(MappingException.class);
|
||||
exception.expectMessage("firstname");
|
||||
exception.expectMessage("lastname");
|
||||
exception.expectMessage("foo");
|
||||
|
||||
MongoMappingContext context = new MongoMappingContext();
|
||||
context.setApplicationContext(applicationContext);
|
||||
context.getPersistentEntity(InvalidPerson.class);
|
||||
}
|
||||
|
||||
class ClassWithMultipleIdProperties {
|
||||
|
||||
@Id
|
||||
@@ -129,15 +102,4 @@ public class MongoMappingContextUnitTests {
|
||||
|
||||
Map<String, SampleClass> children;
|
||||
}
|
||||
|
||||
class Person {
|
||||
|
||||
String firstname, lastname;
|
||||
}
|
||||
|
||||
class InvalidPerson {
|
||||
|
||||
@org.springframework.data.mongodb.core.mapping.Field("foo")
|
||||
String firstname, lastname;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
/*
|
||||
* Copyright 2011-2013 the original author or authors.
|
||||
* Copyright (c) 2011 by the original author(s).
|
||||
*
|
||||
* 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,
|
||||
@@ -13,20 +13,24 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.data.mongodb.core.mapping;
|
||||
|
||||
import org.springframework.data.annotation.Id;
|
||||
import org.springframework.data.mongodb.core.mapping.Document;
|
||||
|
||||
/**
|
||||
* @author Jon Brisbin
|
||||
* @author Jon Brisbin <jbrisbin@vmware.com>
|
||||
*/
|
||||
@Document(collection = "person1")
|
||||
public class PersonCustomCollection1 extends BasePerson {
|
||||
|
||||
@Id
|
||||
@SuppressWarnings("unused")
|
||||
private String id;
|
||||
|
||||
public PersonCustomCollection1(Integer ssn, String firstName, String lastName) {
|
||||
super(ssn, firstName, lastName);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
/*
|
||||
* Copyright 2011-2013 the original author or authors.
|
||||
* Copyright (c) 2011 by the original author(s).
|
||||
*
|
||||
* 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,
|
||||
@@ -13,17 +13,20 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.data.mongodb.core.mapping;
|
||||
|
||||
import org.springframework.data.annotation.Id;
|
||||
import org.springframework.data.mongodb.core.mapping.Document;
|
||||
|
||||
/**
|
||||
* @author Jon Brisbin
|
||||
* @author Jon Brisbin <jbrisbin@vmware.com>
|
||||
*/
|
||||
@Document(collection = "person2")
|
||||
public class PersonCustomCollection2 extends BasePerson {
|
||||
|
||||
@Id
|
||||
@SuppressWarnings("unused")
|
||||
private String id;
|
||||
|
||||
public PersonCustomCollection2(Integer ssn, String firstName, String lastName) {
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
/*
|
||||
* Copyright 2011-2013 the original author or authors.
|
||||
* Copyright (c) 2011 by the original author(s).
|
||||
*
|
||||
* 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,
|
||||
@@ -13,17 +13,20 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.data.mongodb.core.mapping;
|
||||
|
||||
import org.springframework.data.annotation.Id;
|
||||
import org.springframework.data.mongodb.core.mapping.Document;
|
||||
|
||||
/**
|
||||
* @author Jon Brisbin
|
||||
* @author Jon Brisbin <jbrisbin@vmware.com>
|
||||
*/
|
||||
@Document
|
||||
public class PersonMultiDimArrays extends BasePerson {
|
||||
|
||||
@Id
|
||||
@SuppressWarnings("unused")
|
||||
private String id;
|
||||
private String[][] grid;
|
||||
|
||||
|
||||
@@ -0,0 +1,32 @@
|
||||
package org.springframework.data.mongodb.core.mapping;
|
||||
|
||||
import static org.hamcrest.CoreMatchers.*;
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.springframework.data.mongodb.core.mapping.MongoPersistentProperty;
|
||||
import org.springframework.data.mongodb.core.mapping.SimpleMongoMappingContext;
|
||||
import org.springframework.data.mongodb.core.mapping.SimpleMongoMappingContext.SimpleMongoPersistentEntity;
|
||||
|
||||
/**
|
||||
* Unit tests for {@link SimpleMongoMappingContext}.
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
public class SimpleMappingContextUnitTests {
|
||||
|
||||
@Test
|
||||
public void returnsIdPropertyCorrectly() {
|
||||
|
||||
SimpleMongoMappingContext context = new SimpleMongoMappingContext();
|
||||
SimpleMongoPersistentEntity<?> entity = context.getPersistentEntity(Person.class);
|
||||
|
||||
MongoPersistentProperty idProperty = entity.getIdProperty();
|
||||
assertThat(idProperty, is(notNullValue()));
|
||||
assertThat(idProperty.getName(), is("id"));
|
||||
}
|
||||
|
||||
static class Person {
|
||||
String id;
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2011-2013 by the original author(s).
|
||||
* Copyright 2011 by the original author(s).
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -31,7 +31,6 @@ import com.mongodb.DBObject;
|
||||
* Unit tests for {@link AbstractMongoEventListener}.
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
* @author Martin Baumgartner
|
||||
*/
|
||||
public class AbstractMongoEventListenerUnitTests {
|
||||
|
||||
@@ -62,7 +61,7 @@ public class AbstractMongoEventListenerUnitTests {
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATAMONGO-289
|
||||
* @see DATADOC-289
|
||||
*/
|
||||
@Test
|
||||
public void afterLoadEffectGetsHandledCorrectly() {
|
||||
@@ -73,7 +72,7 @@ public class AbstractMongoEventListenerUnitTests {
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATAMONGO-289
|
||||
* @see DATADOC-289
|
||||
*/
|
||||
@Test
|
||||
public void afterLoadEventGetsFilteredForDomainType() {
|
||||
@@ -88,7 +87,7 @@ public class AbstractMongoEventListenerUnitTests {
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATAMONGO-289
|
||||
* @see DATADOC-289
|
||||
*/
|
||||
@Test
|
||||
public void afterLoadEventGetsFilteredForDomainTypeWorksForSubtypes() {
|
||||
@@ -103,7 +102,7 @@ public class AbstractMongoEventListenerUnitTests {
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATAMONGO-289
|
||||
* @see DATADOC-289
|
||||
*/
|
||||
@Test
|
||||
public void afterLoadEventGetsFilteredForDomainTypeWorksForSubtypes2() {
|
||||
@@ -118,7 +117,7 @@ public class AbstractMongoEventListenerUnitTests {
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATAMONGO-333
|
||||
* @see DATADOC-333
|
||||
*/
|
||||
@Test
|
||||
@SuppressWarnings({ "rawtypes", "unchecked" })
|
||||
@@ -128,64 +127,10 @@ public class AbstractMongoEventListenerUnitTests {
|
||||
listener.onApplicationEvent(new MongoMappingEvent(new Object(), new BasicDBObject()));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATAMONGO-545
|
||||
*/
|
||||
@Test
|
||||
public void invokeContactCallbackForPersonEvent() {
|
||||
|
||||
MongoMappingEvent<DBObject> event = new BeforeDeleteEvent<Person>(new BasicDBObject(), Person.class);
|
||||
SampleContactEventListener listener = new SampleContactEventListener();
|
||||
listener.onApplicationEvent(event);
|
||||
|
||||
assertThat(listener.invokedOnBeforeDelete, is(true));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATAMONGO-545
|
||||
*/
|
||||
@Test
|
||||
public void invokePersonCallbackForPersonEvent() {
|
||||
|
||||
MongoMappingEvent<DBObject> event = new BeforeDeleteEvent<Person>(new BasicDBObject(), Person.class);
|
||||
SamplePersonEventListener listener = new SamplePersonEventListener();
|
||||
listener.onApplicationEvent(event);
|
||||
|
||||
assertThat(listener.invokedOnBeforeDelete, is(true));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATAMONGO-545
|
||||
*/
|
||||
@Test
|
||||
public void dontInvokePersonCallbackForAccountEvent() {
|
||||
|
||||
MongoMappingEvent<DBObject> event = new BeforeDeleteEvent<Account>(new BasicDBObject(), Account.class);
|
||||
SamplePersonEventListener listener = new SamplePersonEventListener();
|
||||
listener.onApplicationEvent(event);
|
||||
|
||||
assertThat(listener.invokedOnBeforeDelete, is(false));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATAMONGO-545
|
||||
*/
|
||||
@Test
|
||||
public void donInvokePersonCallbackForUntypedEvent() {
|
||||
|
||||
MongoMappingEvent<DBObject> event = new BeforeDeleteEvent<Account>(new BasicDBObject(), null);
|
||||
SamplePersonEventListener listener = new SamplePersonEventListener();
|
||||
listener.onApplicationEvent(event);
|
||||
|
||||
assertThat(listener.invokedOnBeforeDelete, is(false));
|
||||
}
|
||||
|
||||
class SamplePersonEventListener extends AbstractMongoEventListener<Person> {
|
||||
|
||||
boolean invokedOnBeforeConvert;
|
||||
boolean invokedOnAfterLoad;
|
||||
boolean invokedOnBeforeDelete;
|
||||
boolean invokedOnAfterDelete;
|
||||
|
||||
@Override
|
||||
public void onBeforeConvert(Person source) {
|
||||
@@ -196,24 +141,12 @@ public class AbstractMongoEventListenerUnitTests {
|
||||
public void onAfterLoad(DBObject dbo) {
|
||||
invokedOnAfterLoad = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAfterDelete(DBObject dbo) {
|
||||
invokedOnAfterDelete = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBeforeDelete(DBObject dbo) {
|
||||
invokedOnBeforeDelete = true;
|
||||
}
|
||||
}
|
||||
|
||||
class SampleContactEventListener extends AbstractMongoEventListener<Contact> {
|
||||
|
||||
boolean invokedOnBeforeConvert;
|
||||
boolean invokedOnAfterLoad;
|
||||
boolean invokedOnBeforeDelete;
|
||||
boolean invokedOnAfterDelete;
|
||||
|
||||
@Override
|
||||
public void onBeforeConvert(Contact source) {
|
||||
@@ -224,17 +157,6 @@ public class AbstractMongoEventListenerUnitTests {
|
||||
public void onAfterLoad(DBObject dbo) {
|
||||
invokedOnAfterLoad = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAfterDelete(DBObject dbo) {
|
||||
invokedOnAfterDelete = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBeforeDelete(DBObject dbo) {
|
||||
invokedOnBeforeDelete = true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class SampleAccountEventListener extends AbstractMongoEventListener<Account> {
|
||||
|
||||
@@ -1,49 +0,0 @@
|
||||
/*
|
||||
* Copyright 2013 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.query;
|
||||
|
||||
import static org.hamcrest.CoreMatchers.*;
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
/**
|
||||
* Unit tests for {@link Field}.
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
public class FieldUnitTests {
|
||||
|
||||
@Test
|
||||
public void sameObjectSetupCreatesEqualField() {
|
||||
|
||||
Field left = new Field().elemMatch("key", Criteria.where("foo").is("bar"));
|
||||
Field right = new Field().elemMatch("key", Criteria.where("foo").is("bar"));
|
||||
|
||||
assertThat(left, is(right));
|
||||
assertThat(right, is(left));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void differentObjectSetupCreatesEqualField() {
|
||||
|
||||
Field left = new Field().elemMatch("key", Criteria.where("foo").is("bar"));
|
||||
Field right = new Field().elemMatch("key", Criteria.where("foo").is("foo"));
|
||||
|
||||
assertThat(left, is(not(right)));
|
||||
assertThat(right, is(not(left)));
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2010-2013 the original author or authors.
|
||||
* Copyright 2010-2011 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.
|
||||
@@ -15,32 +15,32 @@
|
||||
*/
|
||||
package org.springframework.data.mongodb.core.query;
|
||||
|
||||
import static org.hamcrest.CoreMatchers.*;
|
||||
import static org.junit.Assert.*;
|
||||
import static org.hamcrest.CoreMatchers.*;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.springframework.data.domain.Sort.Direction;
|
||||
import org.springframework.data.mongodb.core.index.GeospatialIndex;
|
||||
import org.springframework.data.mongodb.core.index.Index;
|
||||
import org.springframework.data.mongodb.core.index.Index.Duplicates;
|
||||
import org.springframework.data.mongodb.core.query.Order;
|
||||
|
||||
public class IndexTests {
|
||||
|
||||
@Test
|
||||
public void testWithAscendingIndex() {
|
||||
Index i = new Index().on("name", Direction.ASC);
|
||||
Index i = new Index().on("name", Order.ASCENDING);
|
||||
assertEquals("{ \"name\" : 1}", i.getIndexKeys().toString());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testWithDescendingIndex() {
|
||||
Index i = new Index().on("name", Direction.DESC);
|
||||
Index i = new Index().on("name", Order.DESCENDING);
|
||||
assertEquals("{ \"name\" : -1}", i.getIndexKeys().toString());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNamedMultiFieldUniqueIndex() {
|
||||
Index i = new Index().on("name", Direction.ASC).on("age", Direction.DESC);
|
||||
Index i = new Index().on("name", Order.ASCENDING).on("age", Order.DESCENDING);
|
||||
i.named("test").unique();
|
||||
assertEquals("{ \"name\" : 1 , \"age\" : -1}", i.getIndexKeys().toString());
|
||||
assertEquals("{ \"name\" : \"test\" , \"unique\" : true}", i.getIndexOptions().toString());
|
||||
@@ -48,7 +48,7 @@ public class IndexTests {
|
||||
|
||||
@Test
|
||||
public void testWithDropDuplicates() {
|
||||
Index i = new Index().on("name", Direction.ASC);
|
||||
Index i = new Index().on("name", Order.ASCENDING);
|
||||
i.unique(Duplicates.DROP);
|
||||
assertEquals("{ \"name\" : 1}", i.getIndexKeys().toString());
|
||||
assertEquals("{ \"unique\" : true , \"dropDups\" : true}", i.getIndexOptions().toString());
|
||||
@@ -56,7 +56,7 @@ public class IndexTests {
|
||||
|
||||
@Test
|
||||
public void testWithSparse() {
|
||||
Index i = new Index().on("name", Direction.ASC);
|
||||
Index i = new Index().on("name", Order.ASCENDING);
|
||||
i.sparse().unique();
|
||||
assertEquals("{ \"name\" : 1}", i.getIndexKeys().toString());
|
||||
assertEquals("{ \"unique\" : true , \"sparse\" : true}", i.getIndexOptions().toString());
|
||||
@@ -72,7 +72,7 @@ public class IndexTests {
|
||||
@Test
|
||||
public void ensuresPropertyOrder() {
|
||||
|
||||
Index on = new Index("foo", Direction.ASC).on("bar", Direction.ASC);
|
||||
Index on = new Index("foo", Order.ASCENDING).on("bar", Order.ASCENDING);
|
||||
assertThat(on.getIndexKeys().toString(), is("{ \"foo\" : 1 , \"bar\" : 1}"));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2010-2013 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.
|
||||
@@ -18,28 +18,14 @@ package org.springframework.data.mongodb.core.query;
|
||||
import static org.hamcrest.CoreMatchers.*;
|
||||
import static org.junit.Assert.*;
|
||||
import static org.springframework.data.mongodb.core.query.Criteria.*;
|
||||
import static org.springframework.data.mongodb.core.query.Query.*;
|
||||
|
||||
import org.junit.Assert;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.rules.ExpectedException;
|
||||
import org.springframework.data.domain.Sort;
|
||||
import org.springframework.data.domain.Sort.Direction;
|
||||
import org.springframework.data.mongodb.InvalidMongoDbApiUsageException;
|
||||
|
||||
/**
|
||||
* Unit tests for {@link Query}.
|
||||
*
|
||||
* @author Thomas Risberg
|
||||
* @author Oliver Gierke
|
||||
* @author Patryk Wasik
|
||||
*/
|
||||
public class QueryTests {
|
||||
|
||||
@Rule
|
||||
public ExpectedException exception = ExpectedException.none();
|
||||
|
||||
@Test
|
||||
public void testSimpleQuery() {
|
||||
Query q = new Query(where("name").is("Thomas").and("age").lt(80));
|
||||
@@ -106,21 +92,6 @@ public class QueryTests {
|
||||
Assert.assertEquals(expectedFields, q.getFieldsObject().toString());
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATAMONGO-652
|
||||
*/
|
||||
@Test
|
||||
public void testQueryWithFieldsElemMatchAndPositionalOperator() {
|
||||
|
||||
Query query = query(where("name").gte("M").lte("T").and("age").not().gt(22));
|
||||
query.fields().elemMatch("products", where("name").is("milk")).position("comments", 2);
|
||||
|
||||
String expected = "{ \"name\" : { \"$gte\" : \"M\" , \"$lte\" : \"T\"} , \"age\" : { \"$not\" : { \"$gt\" : 22}}}";
|
||||
assertThat(query.getQueryObject().toString(), is(expected));
|
||||
String expectedFields = "{ \"products\" : { \"$elemMatch\" : { \"name\" : \"milk\"}} , \"comments.$\" : 2}";
|
||||
assertThat(query.getFieldsObject().toString(), is(expectedFields));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSimpleQueryWithChainedCriteria() {
|
||||
Query q = new Query(where("name").is("Thomas").and("age").lt(80));
|
||||
@@ -181,18 +152,22 @@ public class QueryTests {
|
||||
* @see DATAMONGO-538
|
||||
*/
|
||||
@Test
|
||||
public void addsSortCorrectly() {
|
||||
@SuppressWarnings("deprecation")
|
||||
public void addsDeprecatedSortCorrectly() {
|
||||
|
||||
Query query = new Query();
|
||||
query.sort().on("foo", Order.DESCENDING);
|
||||
|
||||
Query query = new Query().with(new Sort(Direction.DESC, "foo"));
|
||||
assertThat(query.getSortObject().toString(), is("{ \"foo\" : -1}"));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATAMONGO-538
|
||||
*/
|
||||
@Test
|
||||
public void rejectsOrderWithIgnoreCase() {
|
||||
public void addsSortCorrectly() {
|
||||
|
||||
exception.expect(IllegalArgumentException.class);
|
||||
exception.expectMessage("foo");
|
||||
|
||||
new Query().with(new Sort(new Sort.Order("foo").ignoreCase()));
|
||||
Query query = new Query().with(new org.springframework.data.domain.Sort(Direction.DESC, "foo"));
|
||||
assertThat(query.getSortObject().toString(), is("{ \"foo\" : -1}"));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2010-2013 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.
|
||||
@@ -17,27 +17,22 @@ package org.springframework.data.mongodb.core.query;
|
||||
|
||||
import static org.hamcrest.CoreMatchers.*;
|
||||
import static org.junit.Assert.*;
|
||||
import static org.springframework.data.mongodb.core.query.Order.*;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.springframework.data.domain.Sort;
|
||||
import org.springframework.data.domain.Sort.Direction;
|
||||
|
||||
/**
|
||||
* Unit tests for sorting.
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
@SuppressWarnings("deprecation")
|
||||
public class SortTests {
|
||||
|
||||
@Test
|
||||
public void testWithSortAscending() {
|
||||
Query s = new Query().with(new Sort(Direction.ASC, "name"));
|
||||
Sort s = new Sort().on("name", ASCENDING);
|
||||
assertEquals("{ \"name\" : 1}", s.getSortObject().toString());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testWithSortDescending() {
|
||||
Query s = new Query().with(new Sort(Direction.DESC, "name"));
|
||||
Sort s = new Sort().on("name", DESCENDING);
|
||||
assertEquals("{ \"name\" : -1}", s.getSortObject().toString());
|
||||
}
|
||||
|
||||
@@ -46,8 +41,7 @@ public class SortTests {
|
||||
*/
|
||||
@Test
|
||||
public void preservesOrderKeysOnMultipleSorts() {
|
||||
|
||||
Query sort = new Query().with(new Sort(Direction.DESC, "foo").and(new Sort(Direction.DESC, "bar")));
|
||||
Sort sort = new Sort("foo", DESCENDING).on("bar", DESCENDING);
|
||||
assertThat(sort.getSortObject().toString(), is("{ \"foo\" : -1 , \"bar\" : -1}"));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,16 +18,12 @@ package org.springframework.data.mongodb.performance;
|
||||
import static org.springframework.data.mongodb.core.query.Criteria.*;
|
||||
import static org.springframework.data.mongodb.core.query.Query.*;
|
||||
|
||||
import java.text.DecimalFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Random;
|
||||
import java.util.Set;
|
||||
import java.util.regex.Pattern;
|
||||
@@ -39,15 +35,12 @@ import org.springframework.core.Constants;
|
||||
import org.springframework.data.annotation.PersistenceConstructor;
|
||||
import org.springframework.data.mongodb.core.MongoTemplate;
|
||||
import org.springframework.data.mongodb.core.SimpleMongoDbFactory;
|
||||
import org.springframework.data.mongodb.core.convert.MappingMongoConverter;
|
||||
import org.springframework.data.mongodb.core.convert.MongoConverter;
|
||||
import org.springframework.data.mongodb.core.mapping.MongoMappingContext;
|
||||
import org.springframework.data.mongodb.core.index.Indexed;
|
||||
import org.springframework.data.mongodb.core.query.Query;
|
||||
import org.springframework.data.mongodb.repository.MongoRepository;
|
||||
import org.springframework.data.mongodb.repository.support.MongoRepositoryFactoryBean;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.StopWatch;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
import com.mongodb.BasicDBList;
|
||||
import com.mongodb.BasicDBObject;
|
||||
@@ -67,40 +60,29 @@ import com.mongodb.WriteConcern;
|
||||
public class PerformanceTests {
|
||||
|
||||
private static final String DATABASE_NAME = "performance";
|
||||
private static final int NUMBER_OF_PERSONS = 300;
|
||||
private static final int ITERATIONS = 50;
|
||||
private static final int NUMBER_OF_PERSONS = 30000;
|
||||
private static final StopWatch watch = new StopWatch();
|
||||
private static final Collection<String> IGNORED_WRITE_CONCERNS = Arrays.asList("MAJORITY", "REPLICAS_SAFE",
|
||||
"FSYNC_SAFE", "FSYNCED", "JOURNAL_SAFE", "JOURNALED", "REPLICA_ACKNOWLEDGED");
|
||||
"FSYNC_SAFE", "JOURNAL_SAFE");
|
||||
private static final int COLLECTION_SIZE = 1024 * 1024 * 256; // 256 MB
|
||||
private static final Collection<String> COLLECTION_NAMES = Arrays.asList("template", "driver", "person");
|
||||
|
||||
Mongo mongo;
|
||||
MongoTemplate operations;
|
||||
PersonRepository repository;
|
||||
MongoConverter converter;
|
||||
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
|
||||
this.mongo = new Mongo();
|
||||
|
||||
SimpleMongoDbFactory mongoDbFactory = new SimpleMongoDbFactory(this.mongo, DATABASE_NAME);
|
||||
|
||||
MongoMappingContext context = new MongoMappingContext();
|
||||
context.setInitialEntitySet(Collections.singleton(Person.class));
|
||||
context.afterPropertiesSet();
|
||||
|
||||
this.converter = new MappingMongoConverter(mongoDbFactory, context);
|
||||
this.operations = new MongoTemplate(new SimpleMongoDbFactory(this.mongo, DATABASE_NAME), converter);
|
||||
this.operations = new MongoTemplate(new SimpleMongoDbFactory(this.mongo, DATABASE_NAME));
|
||||
|
||||
MongoRepositoryFactoryBean<PersonRepository, Person, ObjectId> factory = new MongoRepositoryFactoryBean<PersonRepository, Person, ObjectId>();
|
||||
factory.setMongoOperations(operations);
|
||||
factory.setRepositoryInterface(PersonRepository.class);
|
||||
factory.afterPropertiesSet();
|
||||
|
||||
this.repository = factory.getObject();
|
||||
|
||||
repository = factory.getObject();
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -108,137 +90,69 @@ public class PerformanceTests {
|
||||
executeWithWriteConcerns(new WriteConcernCallback() {
|
||||
public void doWithWriteConcern(String constantName, WriteConcern concern) {
|
||||
writeHeadline("WriteConcern: " + constantName);
|
||||
System.out.println(String.format("Writing %s objects using plain driver took %sms", NUMBER_OF_PERSONS,
|
||||
writingObjectsUsingPlainDriver(NUMBER_OF_PERSONS)));
|
||||
System.out.println(String.format("Writing %s objects using template took %sms", NUMBER_OF_PERSONS,
|
||||
writingObjectsUsingMongoTemplate(NUMBER_OF_PERSONS)));
|
||||
System.out.println(String.format("Writing %s objects using repository took %sms", NUMBER_OF_PERSONS,
|
||||
writingObjectsUsingRepositories(NUMBER_OF_PERSONS)));
|
||||
writingObjectsUsingPlainDriver("Writing %s objects using plain driver");
|
||||
writingObjectsUsingMongoTemplate("Writing %s objects using template");
|
||||
writingObjectsUsingRepositories("Writing %s objects using repository");
|
||||
writeFooter();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
public void plainConversion() throws InterruptedException {
|
||||
|
||||
Statistics statistics = new Statistics("Plain conversion of " + NUMBER_OF_PERSONS * 100
|
||||
+ " persons - After %s iterations");
|
||||
|
||||
List<DBObject> dbObjects = getPersonDBObjects(NUMBER_OF_PERSONS * 100);
|
||||
|
||||
for (int i = 0; i < ITERATIONS; i++) {
|
||||
statistics.registerTime(Api.DIRECT, Mode.READ, convertDirectly(dbObjects));
|
||||
statistics.registerTime(Api.CONVERTER, Mode.READ, convertUsingConverter(dbObjects));
|
||||
}
|
||||
|
||||
statistics.printResults(ITERATIONS);
|
||||
}
|
||||
|
||||
private long convertDirectly(final List<DBObject> dbObjects) {
|
||||
|
||||
executeWatched(new WatchCallback<List<Person>>() {
|
||||
|
||||
@Override
|
||||
public List<Person> doInWatch() {
|
||||
|
||||
List<Person> persons = new ArrayList<PerformanceTests.Person>();
|
||||
|
||||
for (DBObject dbObject : dbObjects) {
|
||||
persons.add(Person.from(dbObject));
|
||||
}
|
||||
|
||||
return persons;
|
||||
}
|
||||
});
|
||||
|
||||
return watch.getLastTaskTimeMillis();
|
||||
}
|
||||
|
||||
private long convertUsingConverter(final List<DBObject> dbObjects) {
|
||||
|
||||
executeWatched(new WatchCallback<List<Person>>() {
|
||||
|
||||
@Override
|
||||
public List<Person> doInWatch() {
|
||||
|
||||
List<Person> persons = new ArrayList<PerformanceTests.Person>();
|
||||
|
||||
for (DBObject dbObject : dbObjects) {
|
||||
persons.add(converter.read(Person.class, dbObject));
|
||||
}
|
||||
|
||||
return persons;
|
||||
}
|
||||
});
|
||||
|
||||
return watch.getLastTaskTimeMillis();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void writeAndRead() throws Exception {
|
||||
public void writeAndRead() {
|
||||
|
||||
mongo.setWriteConcern(WriteConcern.SAFE);
|
||||
|
||||
readsAndWrites(NUMBER_OF_PERSONS, ITERATIONS);
|
||||
}
|
||||
|
||||
private void readsAndWrites(int numberOfPersons, int iterations) {
|
||||
|
||||
Statistics statistics = new Statistics("Reading " + numberOfPersons + " - After %s iterations");
|
||||
|
||||
for (int i = 0; i < iterations; i++) {
|
||||
for (int i = 3; i > 0; i--) {
|
||||
|
||||
setupCollections();
|
||||
|
||||
statistics.registerTime(Api.DRIVER, Mode.WRITE, writingObjectsUsingPlainDriver(numberOfPersons));
|
||||
statistics.registerTime(Api.TEMPLATE, Mode.WRITE, writingObjectsUsingMongoTemplate(numberOfPersons));
|
||||
statistics.registerTime(Api.REPOSITORY, Mode.WRITE, writingObjectsUsingRepositories(numberOfPersons));
|
||||
writeHeadline("Plain driver");
|
||||
writingObjectsUsingPlainDriver("Writing %s objects using plain driver");
|
||||
readingUsingPlainDriver("Reading all objects using plain driver");
|
||||
queryUsingPlainDriver("Executing query using plain driver");
|
||||
writeFooter();
|
||||
|
||||
statistics.registerTime(Api.DRIVER, Mode.READ, readingUsingPlainDriver());
|
||||
statistics.registerTime(Api.TEMPLATE, Mode.READ, readingUsingTemplate());
|
||||
statistics.registerTime(Api.REPOSITORY, Mode.READ, readingUsingRepository());
|
||||
writeHeadline("Template");
|
||||
writingObjectsUsingMongoTemplate("Writing %s objects using template");
|
||||
readingUsingTemplate("Reading all objects using template");
|
||||
queryUsingTemplate("Executing query using template");
|
||||
writeFooter();
|
||||
|
||||
statistics.registerTime(Api.DRIVER, Mode.QUERY, queryUsingPlainDriver());
|
||||
statistics.registerTime(Api.TEMPLATE, Mode.QUERY, queryUsingTemplate());
|
||||
statistics.registerTime(Api.REPOSITORY, Mode.QUERY, queryUsingRepository());
|
||||
writeHeadline("Repositories");
|
||||
writingObjectsUsingRepositories("Writing %s objects using repository");
|
||||
readingUsingRepository("Reading all objects using repository");
|
||||
queryUsingRepository("Executing query using repository");
|
||||
writeFooter();
|
||||
|
||||
if (i > 0 && i % (iterations / 10) == 0) {
|
||||
statistics.printResults(i);
|
||||
}
|
||||
writeFooter();
|
||||
}
|
||||
|
||||
statistics.printResults(iterations);
|
||||
}
|
||||
|
||||
private void writeHeadline(String headline) {
|
||||
System.out.println(headline);
|
||||
System.out.println(createUnderline(headline));
|
||||
System.out.println("---------------------------------".substring(0, headline.length()));
|
||||
}
|
||||
|
||||
private void writeFooter() {
|
||||
System.out.println();
|
||||
}
|
||||
|
||||
private long queryUsingTemplate() {
|
||||
executeWatched(new WatchCallback<List<Person>>() {
|
||||
private void queryUsingTemplate(String template) {
|
||||
executeWatchedWithTimeAndResultSize(template, new WatchCallback<List<Person>>() {
|
||||
public List<Person> doInWatch() {
|
||||
Query query = query(where("addresses.zipCode").regex(".*1.*"));
|
||||
return operations.find(query, Person.class, "template");
|
||||
}
|
||||
});
|
||||
|
||||
return watch.getLastTaskTimeMillis();
|
||||
}
|
||||
|
||||
private long queryUsingRepository() {
|
||||
executeWatched(new WatchCallback<List<Person>>() {
|
||||
private void queryUsingRepository(String template) {
|
||||
executeWatchedWithTimeAndResultSize(template, new WatchCallback<List<Person>>() {
|
||||
public List<Person> doInWatch() {
|
||||
return repository.findByAddressesZipCodeContaining("1");
|
||||
}
|
||||
});
|
||||
|
||||
return watch.getLastTaskTimeMillis();
|
||||
}
|
||||
|
||||
private void executeWithWriteConcerns(WriteConcernCallback callback) {
|
||||
@@ -267,7 +181,7 @@ public class PerformanceTests {
|
||||
for (String collectionName : COLLECTION_NAMES) {
|
||||
DBCollection collection = db.getCollection(collectionName);
|
||||
collection.drop();
|
||||
collection.getDB().command(getCreateCollectionCommand(collectionName));
|
||||
db.command(getCreateCollectionCommand(collectionName));
|
||||
collection.ensureIndex(new BasicDBObject("firstname", -1));
|
||||
collection.ensureIndex(new BasicDBObject("lastname", -1));
|
||||
}
|
||||
@@ -281,42 +195,38 @@ public class PerformanceTests {
|
||||
return dbObject;
|
||||
}
|
||||
|
||||
private long writingObjectsUsingPlainDriver(int numberOfPersons) {
|
||||
private void writingObjectsUsingPlainDriver(String template) {
|
||||
|
||||
final DBCollection collection = mongo.getDB(DATABASE_NAME).getCollection("driver");
|
||||
final List<Person> persons = getPersonObjects(numberOfPersons);
|
||||
final List<DBObject> persons = getPersonDBObjects();
|
||||
|
||||
executeWatched(new WatchCallback<Void>() {
|
||||
executeWatchedWithTime(template, new WatchCallback<Void>() {
|
||||
public Void doInWatch() {
|
||||
for (Person person : persons) {
|
||||
collection.save(person.toDBObject());
|
||||
for (DBObject person : persons) {
|
||||
collection.save(person);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
});
|
||||
|
||||
return watch.getLastTaskTimeMillis();
|
||||
}
|
||||
|
||||
private long writingObjectsUsingRepositories(int numberOfPersons) {
|
||||
private void writingObjectsUsingRepositories(String template) {
|
||||
|
||||
final List<Person> persons = getPersonObjects(numberOfPersons);
|
||||
final List<Person> persons = getPersonObjects();
|
||||
|
||||
executeWatched(new WatchCallback<Void>() {
|
||||
executeWatchedWithTime(template, new WatchCallback<Void>() {
|
||||
public Void doInWatch() {
|
||||
repository.save(persons);
|
||||
return null;
|
||||
}
|
||||
});
|
||||
|
||||
return watch.getLastTaskTimeMillis();
|
||||
}
|
||||
|
||||
private long writingObjectsUsingMongoTemplate(int numberOfPersons) {
|
||||
private void writingObjectsUsingMongoTemplate(String template) {
|
||||
|
||||
final List<Person> persons = getPersonObjects(numberOfPersons);
|
||||
final List<Person> persons = getPersonObjects();
|
||||
|
||||
executeWatched(new WatchCallback<Void>() {
|
||||
executeWatchedWithTime(template, new WatchCallback<Void>() {
|
||||
public Void doInWatch() {
|
||||
for (Person person : persons) {
|
||||
operations.save(person, "template");
|
||||
@@ -324,95 +234,82 @@ public class PerformanceTests {
|
||||
return null;
|
||||
}
|
||||
});
|
||||
|
||||
return watch.getLastTaskTimeMillis();
|
||||
}
|
||||
|
||||
private long readingUsingPlainDriver() {
|
||||
private void readingUsingPlainDriver(String template) {
|
||||
|
||||
executeWatched(new WatchCallback<List<Person>>() {
|
||||
final DBCollection collection = mongo.getDB(DATABASE_NAME).getCollection("driver");
|
||||
|
||||
executeWatchedWithTimeAndResultSize(String.format(template, NUMBER_OF_PERSONS), new WatchCallback<List<Person>>() {
|
||||
public List<Person> doInWatch() {
|
||||
return toPersons(mongo.getDB(DATABASE_NAME).getCollection("driver").find());
|
||||
return toPersons(collection.find());
|
||||
}
|
||||
});
|
||||
|
||||
return watch.getLastTaskTimeMillis();
|
||||
}
|
||||
|
||||
private long readingUsingTemplate() {
|
||||
executeWatched(new WatchCallback<List<Person>>() {
|
||||
private void readingUsingTemplate(String template) {
|
||||
executeWatchedWithTimeAndResultSize(String.format(template, NUMBER_OF_PERSONS), new WatchCallback<List<Person>>() {
|
||||
public List<Person> doInWatch() {
|
||||
return operations.findAll(Person.class, "template");
|
||||
}
|
||||
});
|
||||
|
||||
return watch.getLastTaskTimeMillis();
|
||||
}
|
||||
|
||||
private long readingUsingRepository() {
|
||||
executeWatched(new WatchCallback<List<Person>>() {
|
||||
private void readingUsingRepository(String template) {
|
||||
executeWatchedWithTimeAndResultSize(String.format(template, NUMBER_OF_PERSONS), new WatchCallback<List<Person>>() {
|
||||
public List<Person> doInWatch() {
|
||||
return repository.findAll();
|
||||
}
|
||||
});
|
||||
|
||||
return watch.getLastTaskTimeMillis();
|
||||
}
|
||||
|
||||
private long queryUsingPlainDriver() {
|
||||
private void queryUsingPlainDriver(String template) {
|
||||
|
||||
executeWatched(new WatchCallback<List<Person>>() {
|
||||
final DBCollection collection = mongo.getDB(DATABASE_NAME).getCollection("driver");
|
||||
|
||||
executeWatchedWithTimeAndResultSize(template, new WatchCallback<List<Person>>() {
|
||||
public List<Person> doInWatch() {
|
||||
|
||||
DBCollection collection = mongo.getDB(DATABASE_NAME).getCollection("driver");
|
||||
|
||||
DBObject regex = new BasicDBObject("$regex", Pattern.compile(".*1.*"));
|
||||
DBObject query = new BasicDBObject("addresses.zipCode", regex);
|
||||
return toPersons(collection.find(query));
|
||||
}
|
||||
});
|
||||
|
||||
return watch.getLastTaskTimeMillis();
|
||||
}
|
||||
|
||||
private List<Person> getPersonObjects(int numberOfPersons) {
|
||||
private List<DBObject> getPersonDBObjects() {
|
||||
|
||||
List<Person> result = new ArrayList<Person>();
|
||||
List<DBObject> result = new ArrayList<DBObject>(NUMBER_OF_PERSONS);
|
||||
|
||||
for (int i = 0; i < numberOfPersons; i++) {
|
||||
|
||||
List<Address> addresses = new ArrayList<Address>();
|
||||
|
||||
for (int a = 0; a < 5; a++) {
|
||||
addresses.add(new Address("zip" + a, "city" + a));
|
||||
}
|
||||
|
||||
Person person = new Person("Firstname" + i, "Lastname" + i, addresses);
|
||||
|
||||
for (int o = 0; o < 10; o++) {
|
||||
person.orders.add(new Order(LineItem.generate()));
|
||||
}
|
||||
|
||||
result.add(person);
|
||||
for (Person person : getPersonObjects()) {
|
||||
result.add(person.toDBObject());
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private List<DBObject> getPersonDBObjects(int numberOfPersons) {
|
||||
private List<Person> getPersonObjects() {
|
||||
|
||||
List<DBObject> dbObjects = new ArrayList<DBObject>(numberOfPersons);
|
||||
List<Person> result = new ArrayList<Person>(NUMBER_OF_PERSONS);
|
||||
|
||||
for (Person person : getPersonObjects(numberOfPersons)) {
|
||||
dbObjects.add(person.toDBObject());
|
||||
watch.start("Created " + NUMBER_OF_PERSONS + " Persons");
|
||||
|
||||
for (int i = 0; i < NUMBER_OF_PERSONS; i++) {
|
||||
|
||||
Address address = new Address("zip" + i, "city" + i);
|
||||
Person person = new Person("Firstname" + i, "Lastname" + i, Arrays.asList(address));
|
||||
person.orders.add(new Order(LineItem.generate()));
|
||||
person.orders.add(new Order(LineItem.generate()));
|
||||
result.add(person);
|
||||
}
|
||||
|
||||
return dbObjects;
|
||||
watch.stop();
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private <T> T executeWatched(WatchCallback<T> callback) {
|
||||
private <T> T executeWatched(String template, WatchCallback<T> callback) {
|
||||
|
||||
watch.start();
|
||||
watch.start(String.format(template, NUMBER_OF_PERSONS));
|
||||
|
||||
try {
|
||||
return callback.doInWatch();
|
||||
@@ -421,6 +318,28 @@ public class PerformanceTests {
|
||||
}
|
||||
}
|
||||
|
||||
private <T> void executeWatchedWithTime(String template, WatchCallback<?> callback) {
|
||||
executeWatched(template, callback);
|
||||
printStatistics(null);
|
||||
}
|
||||
|
||||
private <T> void executeWatchedWithTimeAndResultSize(String template, WatchCallback<List<T>> callback) {
|
||||
printStatistics(executeWatched(template, callback));
|
||||
}
|
||||
|
||||
private void printStatistics(Collection<?> result) {
|
||||
|
||||
long time = watch.getLastTaskTimeMillis();
|
||||
StringBuilder builder = new StringBuilder(watch.getLastTaskName());
|
||||
|
||||
if (result != null) {
|
||||
builder.append(" returned ").append(result.size()).append(" results and");
|
||||
}
|
||||
|
||||
builder.append(" took ").append(time).append(" milliseconds");
|
||||
System.out.println(builder);
|
||||
}
|
||||
|
||||
private static List<Person> toPersons(DBCursor cursor) {
|
||||
|
||||
List<Person> persons = new ArrayList<Person>();
|
||||
@@ -435,9 +354,10 @@ public class PerformanceTests {
|
||||
static class Person {
|
||||
|
||||
ObjectId id;
|
||||
String firstname, lastname;
|
||||
List<Address> addresses;
|
||||
Set<Order> orders;
|
||||
@Indexed
|
||||
final String firstname, lastname;
|
||||
final List<Address> addresses;
|
||||
final Set<Order> orders;
|
||||
|
||||
public Person(String firstname, String lastname, List<Address> addresses) {
|
||||
this.firstname = firstname;
|
||||
@@ -659,253 +579,11 @@ public class PerformanceTests {
|
||||
DBObject toDBObject();
|
||||
}
|
||||
|
||||
private static BasicDBList writeAll(Collection<? extends Convertible> convertibles) {
|
||||
BasicDBList result = new BasicDBList();
|
||||
private static List<DBObject> writeAll(Collection<? extends Convertible> convertibles) {
|
||||
List<DBObject> result = new ArrayList<DBObject>();
|
||||
for (Convertible convertible : convertibles) {
|
||||
result.add(convertible.toDBObject());
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
static enum Api {
|
||||
DRIVER, TEMPLATE, REPOSITORY, DIRECT, CONVERTER;
|
||||
}
|
||||
|
||||
static enum Mode {
|
||||
WRITE, READ, QUERY;
|
||||
}
|
||||
|
||||
private static class Statistics {
|
||||
|
||||
private final String headline;
|
||||
private final Map<Mode, ModeTimes> times;
|
||||
|
||||
public Statistics(String headline) {
|
||||
|
||||
this.headline = headline;
|
||||
this.times = new HashMap<Mode, ModeTimes>();
|
||||
|
||||
for (Mode mode : Mode.values()) {
|
||||
times.put(mode, new ModeTimes(mode));
|
||||
}
|
||||
}
|
||||
|
||||
public void registerTime(Api api, Mode mode, double time) {
|
||||
times.get(mode).add(api, time);
|
||||
}
|
||||
|
||||
public void printResults(int iterations) {
|
||||
|
||||
String title = String.format(headline, iterations);
|
||||
|
||||
System.out.println(title);
|
||||
System.out.println(createUnderline(title));
|
||||
|
||||
StringBuilder builder = new StringBuilder();
|
||||
for (Mode mode : Mode.values()) {
|
||||
String print = times.get(mode).print();
|
||||
if (!print.isEmpty()) {
|
||||
builder.append(print).append('\n');
|
||||
}
|
||||
}
|
||||
|
||||
System.out.println(builder.toString());
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
|
||||
StringBuilder builder = new StringBuilder(times.size());
|
||||
|
||||
for (ModeTimes times : this.times.values()) {
|
||||
builder.append(times.toString());
|
||||
}
|
||||
|
||||
return builder.toString();
|
||||
}
|
||||
}
|
||||
|
||||
private static String createUnderline(String input) {
|
||||
|
||||
StringBuilder builder = new StringBuilder(input.length());
|
||||
|
||||
for (int i = 0; i < input.length(); i++) {
|
||||
builder.append("-");
|
||||
}
|
||||
|
||||
return builder.toString();
|
||||
}
|
||||
|
||||
static class ApiTimes {
|
||||
|
||||
private static final String TIME_TEMPLATE = "%s %s time -\tAverage: %sms%s,%sMedian: %sms%s";
|
||||
|
||||
private static final DecimalFormat TIME_FORMAT;
|
||||
private static final DecimalFormat DEVIATION_FORMAT;
|
||||
|
||||
static {
|
||||
|
||||
TIME_FORMAT = new DecimalFormat("0.00");
|
||||
|
||||
DEVIATION_FORMAT = new DecimalFormat("0.00");
|
||||
DEVIATION_FORMAT.setPositivePrefix("+");
|
||||
}
|
||||
|
||||
private final Api api;
|
||||
private final Mode mode;
|
||||
private final List<Double> times;
|
||||
|
||||
public ApiTimes(Api api, Mode mode) {
|
||||
this.api = api;
|
||||
this.mode = mode;
|
||||
this.times = new ArrayList<Double>();
|
||||
}
|
||||
|
||||
public void add(double time) {
|
||||
this.times.add(time);
|
||||
}
|
||||
|
||||
public boolean hasTimes() {
|
||||
return !times.isEmpty();
|
||||
}
|
||||
|
||||
public double getAverage() {
|
||||
|
||||
double result = 0;
|
||||
|
||||
for (Double time : times) {
|
||||
result += time;
|
||||
}
|
||||
|
||||
return result == 0.0 ? 0.0 : result / times.size();
|
||||
}
|
||||
|
||||
public double getMedian() {
|
||||
|
||||
if (times.isEmpty()) {
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
ArrayList<Double> list = new ArrayList<Double>(times);
|
||||
Collections.sort(list);
|
||||
|
||||
int size = list.size();
|
||||
|
||||
if (size % 2 == 0) {
|
||||
return (list.get(size / 2 - 1) + list.get(size / 2)) / 2;
|
||||
} else {
|
||||
return list.get(size / 2);
|
||||
}
|
||||
}
|
||||
|
||||
private double getDeviationFrom(double otherAverage) {
|
||||
|
||||
double average = getAverage();
|
||||
return average * 100 / otherAverage - 100;
|
||||
}
|
||||
|
||||
private double getMediaDeviationFrom(double otherMedian) {
|
||||
double median = getMedian();
|
||||
return median * 100 / otherMedian - 100;
|
||||
}
|
||||
|
||||
public String print() {
|
||||
|
||||
if (times.isEmpty()) {
|
||||
return "";
|
||||
}
|
||||
|
||||
return basicPrint("", "\t\t", "") + '\n';
|
||||
}
|
||||
|
||||
private String basicPrint(String extension, String middle, String foo) {
|
||||
return String.format(TIME_TEMPLATE, api, mode, TIME_FORMAT.format(getAverage()), extension, middle,
|
||||
TIME_FORMAT.format(getMedian()), foo);
|
||||
}
|
||||
|
||||
public String print(double referenceAverage, double referenceMedian) {
|
||||
|
||||
if (times.isEmpty()) {
|
||||
return "";
|
||||
}
|
||||
|
||||
return basicPrint(String.format(" %s%%", DEVIATION_FORMAT.format(getDeviationFrom(referenceAverage))), "\t",
|
||||
String.format(" %s%%", DEVIATION_FORMAT.format(getMediaDeviationFrom(referenceMedian)))) + '\n';
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see java.lang.Object#toString()
|
||||
*/
|
||||
@Override
|
||||
public String toString() {
|
||||
return times.isEmpty() ? "" : String.format("%s, %s: %s", api, mode,
|
||||
StringUtils.collectionToCommaDelimitedString(times)) + '\n';
|
||||
}
|
||||
}
|
||||
|
||||
static class ModeTimes {
|
||||
|
||||
private final Map<Api, ApiTimes> times;
|
||||
|
||||
public ModeTimes(Mode mode) {
|
||||
|
||||
this.times = new HashMap<Api, ApiTimes>();
|
||||
|
||||
for (Api api : Api.values()) {
|
||||
this.times.put(api, new ApiTimes(api, mode));
|
||||
}
|
||||
}
|
||||
|
||||
public void add(Api api, double time) {
|
||||
times.get(api).add(time);
|
||||
}
|
||||
|
||||
@SuppressWarnings("null")
|
||||
public String print() {
|
||||
|
||||
if (times.isEmpty()) {
|
||||
return "";
|
||||
}
|
||||
|
||||
Double previousTime = null;
|
||||
Double previousMedian = null;
|
||||
StringBuilder builder = new StringBuilder();
|
||||
|
||||
for (Api api : Api.values()) {
|
||||
|
||||
ApiTimes apiTimes = times.get(api);
|
||||
|
||||
if (!apiTimes.hasTimes()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (previousTime == null) {
|
||||
builder.append(apiTimes.print());
|
||||
previousTime = apiTimes.getAverage();
|
||||
previousMedian = apiTimes.getMedian();
|
||||
} else {
|
||||
builder.append(apiTimes.print(previousTime, previousMedian));
|
||||
}
|
||||
}
|
||||
|
||||
return builder.toString();
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see java.lang.Object#toString()
|
||||
*/
|
||||
@Override
|
||||
public String toString() {
|
||||
|
||||
StringBuilder builder = new StringBuilder(times.size());
|
||||
|
||||
for (ApiTimes times : this.times.values()) {
|
||||
builder.append(times.toString());
|
||||
}
|
||||
|
||||
return builder.toString();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -546,28 +546,4 @@ public abstract class AbstractPersonRepositoryIntegrationTests {
|
||||
assertThat(result, hasSize(1));
|
||||
assertThat(result, hasItem(dave));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATAMONGO-636
|
||||
*/
|
||||
@Test
|
||||
public void executesDerivedCountProjection() {
|
||||
assertThat(repository.countByLastname("Matthews"), is(2L));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATAMONGO-636
|
||||
*/
|
||||
@Test
|
||||
public void executesDerivedCountProjectionToInt() {
|
||||
assertThat(repository.countByFirstname("Oliver August"), is(1));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATAMONGO-636
|
||||
*/
|
||||
@Test
|
||||
public void executesAnnotatedCountProjection() {
|
||||
assertThat(repository.someCountQuery("Matthews"), is(2L));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -198,20 +198,4 @@ public interface PersonRepository extends MongoRepository<Person, String>, Query
|
||||
* @return
|
||||
*/
|
||||
List<Person> findByCredentials(Credentials credentials);
|
||||
|
||||
/**
|
||||
* @see DATAMONGO-636
|
||||
*/
|
||||
long countByLastname(String lastname);
|
||||
|
||||
/**
|
||||
* @see DATAMONGO-636
|
||||
*/
|
||||
int countByFirstname(String firstname);
|
||||
|
||||
/**
|
||||
* @see DATAMONGO-636
|
||||
*/
|
||||
@Query(value = "{ 'lastname' : ?0 }", count = true)
|
||||
long someCountQuery(String lastname);
|
||||
}
|
||||
|
||||
@@ -1,130 +0,0 @@
|
||||
/*
|
||||
* 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.
|
||||
* 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.repository.support;
|
||||
|
||||
import static org.hamcrest.Matchers.*;
|
||||
import static org.junit.Assert.assertThat;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.data.mongodb.core.MongoTemplate;
|
||||
import org.springframework.data.mongodb.repository.Person;
|
||||
import org.springframework.data.mongodb.repository.Person.Sex;
|
||||
import org.springframework.data.mongodb.repository.query.MongoEntityInformation;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:kowsercse@gmail.com">A. B. M. Kowser</a>
|
||||
*/
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
@ContextConfiguration("classpath:infrastructure.xml")
|
||||
public class SimpleMongoRepositoryTests {
|
||||
|
||||
@Autowired
|
||||
private MongoTemplate template;
|
||||
|
||||
private Person oliver, dave, carter, boyd, stefan, leroi, alicia;
|
||||
private List<Person> all;
|
||||
|
||||
private MongoEntityInformation<Person, String> personEntityInformation = new CustomizedPersonInformation();
|
||||
private SimpleMongoRepository<Person, String> repository;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
repository = new SimpleMongoRepository<Person, String>(personEntityInformation, template);
|
||||
repository.deleteAll();
|
||||
|
||||
oliver = new Person("Oliver August", "Matthews", 4);
|
||||
dave = new Person("Dave", "Matthews", 42);
|
||||
carter = new Person("Carter", "Beauford", 49);
|
||||
boyd = new Person("Boyd", "Tinsley", 45);
|
||||
stefan = new Person("Stefan", "Lessard", 34);
|
||||
leroi = new Person("Leroi", "Moore", 41);
|
||||
alicia = new Person("Alicia", "Keys", 30, Sex.FEMALE);
|
||||
|
||||
all = repository.save(Arrays.asList(oliver, dave, carter, boyd, stefan, leroi, alicia));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void findALlFromCustomCollectionName() {
|
||||
List<Person> result = repository.findAll();
|
||||
assertThat(result, hasSize(all.size()));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void findOneFromCustomCollectionName() {
|
||||
Person result = repository.findOne(dave.getId());
|
||||
assertThat(result, is(dave));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void deleteFromCustomCollectionName() {
|
||||
repository.delete(dave);
|
||||
List<Person> result = repository.findAll();
|
||||
|
||||
assertThat(result, hasSize(all.size() - 1));
|
||||
assertThat(result, not(hasItem(dave)));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void deleteByIdFromCustomCollectionName() {
|
||||
repository.delete(dave.getId());
|
||||
List<Person> result = repository.findAll();
|
||||
|
||||
assertThat(result, hasSize(all.size() - 1));
|
||||
assertThat(result, not(hasItem(dave)));
|
||||
}
|
||||
|
||||
private static class CustomizedPersonInformation implements MongoEntityInformation<Person, String> {
|
||||
|
||||
@Override
|
||||
public boolean isNew(Person entity) {
|
||||
return entity.getId() == null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getId(Person entity) {
|
||||
return entity.getId();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<String> getIdType() {
|
||||
return String.class;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<Person> getJavaType() {
|
||||
return Person.class;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCollectionName() {
|
||||
return "customizedPerson";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getIdAttribute() {
|
||||
return "id";
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -10,7 +10,5 @@
|
||||
</mongo:mapping-converter>
|
||||
|
||||
<mongo:db-factory id="factory" />
|
||||
|
||||
<mongo:mapping-converter id="abbreviatingConverter" abbreviate-field-names="true" />
|
||||
|
||||
</beans>
|
||||
|
||||
@@ -51,10 +51,13 @@
|
||||
|
||||
<bean id="readConverter" class="org.springframework.data.mongodb.core.PersonReadConverter"/>
|
||||
|
||||
<mongo:template id="mongoTemplate" db-factory-ref="mongoDbFactory" converter-ref="mappingConverter"/>
|
||||
<mongo:template id="anotherMongoTemplate" db-factory-ref="mongoDbFactory" write-concern="SAFE" />
|
||||
|
||||
<mongo:gridFsTemplate/>
|
||||
<mongo:gridFsTemplate id="antoherGridFsTemplate" db-factory-ref="mongoDbFactory" converter-ref="mappingConverter"/>
|
||||
<bean id="mongoTemplate" class="org.springframework.data.mongodb.core.MongoTemplate">
|
||||
<constructor-arg name="mongoDbFactory" ref="mongoDbFactory"/>
|
||||
<constructor-arg name="mongoConverter" ref="mappingConverter"/>
|
||||
</bean>
|
||||
|
||||
<bean id="anotherMongoTemplate" class="org.springframework.data.mongodb.core.MongoTemplate">
|
||||
<constructor-arg name="mongoDbFactory" ref="mongoDbFactory"/>
|
||||
</bean>
|
||||
|
||||
</beans>
|
||||
|
||||
@@ -52,7 +52,7 @@
|
||||
<xi:include href="introduction/why-sd-doc.xml"/>
|
||||
<xi:include href="introduction/requirements.xml"/>
|
||||
<xi:include href="introduction/getting-started.xml"/>
|
||||
<xi:include href="https://raw.github.com/SpringSource/spring-data-commons/1.6.0.M1/src/docbkx/repositories.xml">
|
||||
<xi:include href="https://github.com/SpringSource/spring-data-commons/raw/1.4.0.RELEASE/src/docbkx/repositories.xml">
|
||||
<xi:fallback href="../../../spring-data-commons/src/docbkx/repositories.xml" />
|
||||
</xi:include>
|
||||
</part>
|
||||
@@ -72,10 +72,10 @@
|
||||
<part id="appendix">
|
||||
<title>Appendix</title>
|
||||
|
||||
<xi:include href="https://raw.github.com/SpringSource/spring-data-commons/1.6.0.M1/src/docbkx/repository-namespace-reference.xml">
|
||||
<xi:include href="https://raw.github.com/SpringSource/spring-data-commons/1.4.0.RELEASE/src/docbkx/repository-namespace-reference.xml">
|
||||
<xi:fallback href="../../../spring-data-commons/src/docbkx/repository-namespace-reference.xml" />
|
||||
</xi:include>
|
||||
<xi:include href="https://raw.github.com/SpringSource/spring-data-commons/1.6.0.M1/src/docbkx/repository-query-keywords-reference.xml">
|
||||
<xi:include href="https://raw.github.com/SpringSource/spring-data-commons/1.4.0.RELEASE/src/docbkx/repository-query-keywords-reference.xml">
|
||||
<xi:fallback href="../../../spring-data-commons/src/docbkx/repository-query-keywords-reference.xml" />
|
||||
</xi:include>
|
||||
</part>
|
||||
|
||||
@@ -1,64 +1,6 @@
|
||||
Spring Data MongoDB Changelog
|
||||
=============================
|
||||
|
||||
Changes in version 1.3.0.M1 (2013-06-04)
|
||||
----------------------------------------
|
||||
** Bug
|
||||
* [DATAMONGO-571] - Spring Data for MongoDb doesn't save null values when @Version is added to domain class
|
||||
* [DATAMONGO-612] - Fix PDF reference documentation name
|
||||
* [DATAMONGO-613] - Images missing from reference documentation
|
||||
* [DATAMONGO-617] - NullPointerException in MongoTemplate.initializeVersionProperty(…)
|
||||
* [DATAMONGO-620] - MongoTemplate.doSaveVersioned(…) does not consider collection handed into the method
|
||||
* [DATAMONGO-621] - MongoTemplate.initializeVersionProperty(…) does not use ConversionService
|
||||
* [DATAMONGO-622] - An unversioned object should be created using insert(…) instead of save.
|
||||
* [DATAMONGO-629] - Different results when using count and find with the same criteria with 'id' field
|
||||
* [DATAMONGO-638] - MappingContext should not create PersistentEntity instances for native maps
|
||||
* [DATAMONGO-640] - MongoLog4jAppender suffers from potential NullPointerException when closing Mongo instance
|
||||
* [DATAMONGO-641] - MongoLog4jAppender suffers from potential NullPointerException when closing Mongo instance
|
||||
* [DATAMONGO-642] - MongoChangeSetPersister does not use mapped collection name
|
||||
* [DATAMONGO-646] - Can't insert DBObjects through MongoTemplate
|
||||
* [DATAMONGO-648] - ID attributes in namespace shouldn't be XSD IDs
|
||||
* [DATAMONGO-663] - org.springframework.data.mongodb.core.query.Field needs an equals method
|
||||
* [DATAMONGO-669] - Incompatibility with Querydsl 3.1.1
|
||||
* [DATAMONGO-676] - SimpleMongoRepository fails if used with customized collection name
|
||||
* [DATAMONGO-677] - QueryMapper does not handled correctly Map with DBRef value
|
||||
* [DATAMONGO-679] - MongoTemplate.doSave(…) passed a JSON String doesn't save it.
|
||||
* [DATAMONGO-683] - QueryMapper does not handle default _id when no MappingMetadata is present
|
||||
|
||||
** Improvement
|
||||
* [DATAMONGO-140] - Add XML namespace element for MongoTemplate
|
||||
* [DATAMONGO-545] - Add before delete and after delete events for AbstractMongoEventListener
|
||||
* [DATAMONGO-554] - Add background attribute to @Indexed and @CompoundIndex
|
||||
* [DATAMONGO-569] - AbstractMongoConfiguration cannot be used on CloudFoundry
|
||||
* [DATAMONGO-594] - cross-store=> Define document name using annotation
|
||||
* [DATAMONGO-631] - Explicitly prevent an Order instance set to ignore case from being piped into a query
|
||||
* [DATAMONGO-632] - Polish namespace XSD to avoid errors in STS
|
||||
* [DATAMONGO-633] - Upgrade to Querydsl 3.0.0
|
||||
* [DATAMONGO-634] - Inherit application scope from basic CDI bean of Spring Data Commons
|
||||
* [DATAMONGO-635] - Fix some Sonar warnings
|
||||
* [DATAMONGO-636] - Add support for countBy projections
|
||||
* [DATAMONGO-637] - Typo in Query.query(…)
|
||||
* [DATAMONGO-651] - WriteResult not available from thrown Exception
|
||||
* [DATAMONGO-652] - Add support for elemMatch and positional operator projections
|
||||
* [DATAMONGO-656] - Potential NullPointerException when debugging in MongoTemplate
|
||||
* [DATAMONGO-657] - Allow to write Map value as DBRef
|
||||
* [DATAMONGO-666] - Fix architecture inconsistency created by MongoDataIntegrityViolationException
|
||||
* [DATAMONGO-680] - SimpleMongoRepository.exists(ID) improvement
|
||||
* [DATAMONGO-681] - Expose MongoTemplate.exists() method
|
||||
* [DATAMONGO-682] - Remove performance hotspots
|
||||
|
||||
** New Feature
|
||||
* [DATAMONGO-607] - Add an abbreviating field naming strategy
|
||||
* [DATAMONGO-628] - Add XML namespace elements for MongoTemplate and GridFsTemplate
|
||||
|
||||
** Task
|
||||
* [DATAMONGO-597] - Website is severely out-of-date
|
||||
* [DATAMONGO-658] - Minor formatting changes to README.md
|
||||
* [DATAMONGO-667] - Remove deprecations and further deprecate sorting/ordering types
|
||||
* [DATAMONGO-672] - Upgrade to latest Spring Data Build and Commons
|
||||
* [DATAMONGO-678] - Performance improvements in CustomConversions
|
||||
* [DATAMONGO-690] - Release 1.3 M1
|
||||
|
||||
Changes in version 1.2.1.GA (2013-04-17)
|
||||
----------------------------------------
|
||||
** Bug
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
Spring Data Document 1.3 M1
|
||||
Spring Data Document 1.2.1
|
||||
Copyright (c) [2010-2013] SpringSource, a division of VMware, Inc.
|
||||
|
||||
This product is licensed to you under the Apache License, Version 2.0 (the "License").
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
SPRING DATA MongoDB 1.3.0.M1
|
||||
SPRING DATA MongoDB 1.2.1.GA
|
||||
----------------------------
|
||||
|
||||
Spring Data MongoDB is released under the terms of the Apache Software License Version 2.0 (see license.txt).
|
||||
|
||||
Reference in New Issue
Block a user