Compare commits
82 Commits
1.1.x
...
1.2.3.RELE
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
11d9f04fd1 | ||
|
|
67b91e446e | ||
|
|
1124841e17 | ||
|
|
10ccbf131d | ||
|
|
b29930b512 | ||
|
|
d671fb13ae | ||
|
|
b0a10d19c3 | ||
|
|
d8ef7e1472 | ||
|
|
b9a25eabae | ||
|
|
e92e5c737f | ||
|
|
6e46fb12cb | ||
|
|
031d446a1c | ||
|
|
e6bab1ce60 | ||
|
|
2fffe0a5c4 | ||
|
|
2493de5f91 | ||
|
|
bd11bab076 | ||
|
|
b667984563 | ||
|
|
7ef167ed96 | ||
|
|
303a057d86 | ||
|
|
607072c0d3 | ||
|
|
11e9c562b3 | ||
|
|
220b211faa | ||
|
|
c0c51fcc29 | ||
|
|
ed9eddf10e | ||
|
|
e23d73d55e | ||
|
|
9627fbaebf | ||
|
|
ef93d4db0b | ||
|
|
928b5a7742 | ||
|
|
118a52a8d6 | ||
|
|
b47e8ca3da | ||
|
|
8527d6eb43 | ||
|
|
d645c778c3 | ||
|
|
5c47f1ae9e | ||
|
|
9f324bac19 | ||
|
|
186caba1ac | ||
|
|
2ebb7e801d | ||
|
|
a932f3474e | ||
|
|
e992456532 | ||
|
|
7b34c5cac4 | ||
|
|
16baf00f5e | ||
|
|
61a2c56a27 | ||
|
|
e62437b64a | ||
|
|
e9a7e887be | ||
|
|
b91a66f6f9 | ||
|
|
a047e54e5a | ||
|
|
8197ff57c8 | ||
|
|
a2136719e1 | ||
|
|
7bcf142c8d | ||
|
|
d50d03a80e | ||
|
|
ba894a4511 | ||
|
|
2bc6ebc250 | ||
|
|
909110cf4e | ||
|
|
ba094da5a7 | ||
|
|
876b31bc52 | ||
|
|
dc8e8281eb | ||
|
|
48deb1a150 | ||
|
|
48625956b7 | ||
|
|
782cf6e10d | ||
|
|
c28e51cf86 | ||
|
|
4b1065cac5 | ||
|
|
c807b2abcf | ||
|
|
19ad2d3aac | ||
|
|
bd7fe5bfd3 | ||
|
|
a237999037 | ||
|
|
d8a9752724 | ||
|
|
4c8bf0dec2 | ||
|
|
cffc27d83a | ||
|
|
42ab4cb7b4 | ||
|
|
42df25434f | ||
|
|
4e16f7ebe2 | ||
|
|
04a87b373d | ||
|
|
c4eca7eadd | ||
|
|
3a9dc2b98c | ||
|
|
c568b7cbc2 | ||
|
|
9482350062 | ||
|
|
772a140def | ||
|
|
936259a766 | ||
|
|
533d21281e | ||
|
|
6977fa87e6 | ||
|
|
41dcebb010 | ||
|
|
ef077182f6 | ||
|
|
21e7c63766 |
133
README.md
133
README.md
@@ -29,19 +29,13 @@ For those in a hurry:
|
||||
|
||||
* Download the jar through Maven:
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.data</groupId>
|
||||
<artifactId>spring-data-mongodb</artifactId>
|
||||
<version>1.0.0.BUILD-SNAPSHOT</version>
|
||||
</dependency>
|
||||
|
||||
|
||||
<repository>
|
||||
<id>spring-maven-snapshot</id>
|
||||
<snapshots><enabled>true</enabled></snapshots>
|
||||
<name>Springframework Maven SNAPSHOT Repository</name>
|
||||
<url>http://maven.springframework.org/snapshot</url>
|
||||
</repository>
|
||||
```xml
|
||||
<dependency>
|
||||
<groupId>org.springframework.data</groupId>
|
||||
<artifactId>spring-data-mongodb</artifactId>
|
||||
<version>1.2.3.RELEASE</version>
|
||||
</dependency>
|
||||
```
|
||||
|
||||
### MongoTemplate
|
||||
MongoTemplate is the central support class for Mongo database operations. It provides
|
||||
@@ -54,93 +48,98 @@ Future plans are to support optional logging and/or exception throwing based on
|
||||
|
||||
### Easy Data Repository generation
|
||||
|
||||
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.
|
||||
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
|
||||
|
||||
public interface Repository<T, ID extends Serializable> {
|
||||
```java
|
||||
public interface Repository<T, ID extends Serializable> {
|
||||
|
||||
T save(T entity);
|
||||
T save(T entity);
|
||||
|
||||
List<T> save(Iterable<? extends T> entities);
|
||||
List<T> save(Iterable<? extends T> entities);
|
||||
|
||||
T findById(ID id);
|
||||
T findById(ID id);
|
||||
|
||||
boolean exists(ID id);
|
||||
boolean exists(ID id);
|
||||
|
||||
List<T> findAll();
|
||||
List<T> findAll();
|
||||
|
||||
Long count();
|
||||
Long count();
|
||||
|
||||
void delete(T entity);
|
||||
void delete(T entity);
|
||||
|
||||
void delete(Iterable<? extends T> entities);
|
||||
void delete(Iterable<? extends T> entities);
|
||||
|
||||
void deleteAll();
|
||||
}
|
||||
void deleteAll();
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
The MongoRepository extends Repository and will in future add more Mongo specific methods.
|
||||
The `MongoRepository` extends `Repository` and will in future add more Mongo specific methods.
|
||||
|
||||
public interface MongoRepository<T, ID extends Serializable> extends
|
||||
Repository<T, ID> {
|
||||
}
|
||||
```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.
|
||||
`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.
|
||||
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
|
||||
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
|
||||
|
||||
public interface PersonRepository extends MongoRepository<Person, Long> {
|
||||
```java
|
||||
public interface PersonRepository extends MongoRepository<Person, Long> {
|
||||
|
||||
List<Person> findByLastname(String lastname);
|
||||
List<Person> findByLastname(String lastname);
|
||||
|
||||
List<Person> findByFirstnameLike(String firstname);
|
||||
}
|
||||
List<Person> findByFirstnameLike(String firstname);
|
||||
}
|
||||
```
|
||||
|
||||
You can have Spring automatically generate the implemention as shown below
|
||||
You can have Spring automatically create a proxy for the interface as shown below:
|
||||
|
||||
<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" />
|
||||
<property name="defaultCollectionName" value="springdata" />
|
||||
</bean>
|
||||
```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" />
|
||||
<property name="defaultCollectionName" value="springdata" />
|
||||
</bean>
|
||||
|
||||
<bean class="org.springframework.data.document.mongodb.repository.MongoRepositoryFactoryBean">
|
||||
<property name="template" ref="template" />
|
||||
<property name="repositoryInterface" value="org.springframework.data.document.mongodb.repository.PersonRepository" />
|
||||
</bean>
|
||||
<mongo:repositories base-package="com.acme.repository" />
|
||||
```
|
||||
|
||||
This will register an object in the container named PersonRepository. 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:
|
||||
|
||||
@Service
|
||||
public class MyService {
|
||||
``java
|
||||
@Service
|
||||
public class MyService {
|
||||
|
||||
@Autowired
|
||||
PersonRepository repository;
|
||||
@Autowired
|
||||
private final PersonRepository repository;
|
||||
|
||||
public void doWork() {
|
||||
|
||||
public void doWork() {
|
||||
repository.deleteAll();
|
||||
|
||||
repository.deleteAll();
|
||||
Person person = new Person();
|
||||
person.setFirstname("Oliver");
|
||||
person.setLastname("Gierke");
|
||||
person = repository.save(person);
|
||||
|
||||
Person person = new Person();
|
||||
person.setFirstname("Oliver");
|
||||
person.setLastname("Gierke");
|
||||
person = repository.save(person);
|
||||
List<Person> lastNameResults = repository.findByLastname("Gierke");
|
||||
|
||||
List<Person> lastNameResults = repository.findByLastname("Gierke");
|
||||
List<Person> firstNameResults = repository.findByFirstnameLike("Oli*");
|
||||
|
||||
List<Person> firstNameResults = repository.findByFirstnameLike("Oli*");
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
Contributing to Spring Data
|
||||
|
||||
@@ -73,7 +73,7 @@
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_declaration" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_parameters" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_block_comment" value="false"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_in_empty_type_declaration" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_in_empty_type_declaration" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.lineSplit" value="120"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_if" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_between_brackets_in_array_type_reference" value="do not insert"/>
|
||||
@@ -102,7 +102,7 @@
|
||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_parameters_in_constructor_declaration" value="16"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_colon_in_labeled_statement" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_annotation_type_declaration" value="end_of_line"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_in_empty_method_body" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_in_empty_method_body" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_method_declaration" value="0"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_invocation" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_try" value="do not insert"/>
|
||||
@@ -124,7 +124,7 @@
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_throw" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_arguments" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.compiler.problem.enumIdentifier" value="error"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_switch" value="false"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_switch" value="true"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_ellipsis" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_block" value="end_of_line"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_inits" value="do not insert"/>
|
||||
@@ -135,9 +135,9 @@
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_increments" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.format_line_comment_starting_on_first_column" value="true"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_reference" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_field" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_enum_constant" value="end_of_line"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_field" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.comment.indent_root_tags" value="true"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_enum_constant" value="end_of_line"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_declarations" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_union_type_in_multicatch" value="16"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_explicitconstructorcall_arguments" value="insert"/>
|
||||
@@ -150,12 +150,12 @@
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_opening_brace_in_array_initializer" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_closing_brace_in_block" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_reference" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_constant" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_constant" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_arguments" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_constructor_declaration" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_throws" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_if" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_javadoc_comment" value="false"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_javadoc_comment" value="true"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_constructor_declaration" value="16"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_assignment_operator" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_assignment_operator" value="insert"/>
|
||||
@@ -182,11 +182,11 @@
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_parameterized_type_reference" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_anonymous_type_declaration" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.keep_empty_array_initializer_on_one_line" value="false"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_declaration" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_declaration" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.keep_imple_if_on_one_line" value="false"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_parameters" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_parameters" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_at_end_of_file_if_missing" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_at_end_of_file_if_missing" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_colon_in_for" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_labeled_statement" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_parameterized_type_reference" value="do not insert"/>
|
||||
@@ -237,7 +237,7 @@
|
||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_method_declaration" value="16"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_parameters" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_allocation_expression" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_in_empty_anonymous_type_declaration" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_in_empty_anonymous_type_declaration" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_colon_in_conditional" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_parameterized_type_reference" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_for" value="do not insert"/>
|
||||
@@ -251,12 +251,12 @@
|
||||
<setting id="org.eclipse.jdt.core.compiler.codegen.targetPlatform" value="1.7"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_resources_in_try" value="80"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.use_tabs_only_for_leading_indentations" value="false"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_annotation" value="0"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_annotation" value="16"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.comment.format_header" value="false"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.comment.format_block_comments" value="false"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_enum_constant" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_enum_constants" value="0"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_in_empty_block" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_in_empty_block" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_annotation_declaration_header" value="true"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_parenthesized_expression" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_parenthesized_expression" value="do not insert"/>
|
||||
|
||||
378
pom.xml
378
pom.xml
@@ -1,297 +1,99 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<groupId>org.springframework.data</groupId>
|
||||
<artifactId>spring-data-mongodb-dist</artifactId>
|
||||
<name>Spring Data MongoDB Distribution</name>
|
||||
<description>Spring Data project for MongoDB</description>
|
||||
<url>http://www.springsource.org/spring-data/mongodb</url>
|
||||
<version>1.1.3.BUILD-SNAPSHOT</version>
|
||||
<packaging>pom</packaging>
|
||||
<modules>
|
||||
<module>spring-data-mongodb</module>
|
||||
<module>spring-data-mongodb-cross-store</module>
|
||||
<module>spring-data-mongodb-log4j</module>
|
||||
<module>spring-data-mongodb-parent</module>
|
||||
</modules>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
|
||||
<developers>
|
||||
<developer>
|
||||
<id>trisberg</id>
|
||||
<name>Thomas Risberg</name>
|
||||
<email>trisberg at vmware.com</email>
|
||||
<organization>SpringSource</organization>
|
||||
<organizationUrl>http://www.SpringSource.com</organizationUrl>
|
||||
<roles>
|
||||
<role>Project Admin</role>
|
||||
<role>Developer</role>
|
||||
</roles>
|
||||
<timezone>-5</timezone>
|
||||
</developer>
|
||||
<developer>
|
||||
<id>mpollack</id>
|
||||
<name>Mark Pollack</name>
|
||||
<email>mpollack at vmware.com</email>
|
||||
<organization>SpringSource</organization>
|
||||
<organizationUrl>http://www.SpringSource.com</organizationUrl>
|
||||
<roles>
|
||||
<role>Project Admin</role>
|
||||
<role>Developer</role>
|
||||
</roles>
|
||||
<timezone>-5</timezone>
|
||||
</developer>
|
||||
<developer>
|
||||
<id>ogierke</id>
|
||||
<name>Oliver Gierke</name>
|
||||
<email>ogierke at vmware.com</email>
|
||||
<organization>SpringSource</organization>
|
||||
<organizationUrl>http://www.springsource.com</organizationUrl>
|
||||
<roles>
|
||||
<role>Developer</role>
|
||||
</roles>
|
||||
<timezone>+1</timezone>
|
||||
</developer>
|
||||
<developer>
|
||||
<id>jbrisbin</id>
|
||||
<name>Jon Brisbin</name>
|
||||
<email>jbrisbin at vmware.com</email>
|
||||
<organization>SpringSource</organization>
|
||||
<organizationUrl>http://www.springsource.com</organizationUrl>
|
||||
<roles>
|
||||
<role>Developer</role>
|
||||
</roles>
|
||||
<timezone>-6</timezone>
|
||||
</developer>
|
||||
</developers>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<groupId>org.springframework.data</groupId>
|
||||
<artifactId>spring-data-mongodb-parent</artifactId>
|
||||
<version>1.2.3.RELEASE</version>
|
||||
<packaging>pom</packaging>
|
||||
|
||||
<licenses>
|
||||
<license>
|
||||
<name>Apache License, Version 2.0</name>
|
||||
<url>http://www.apache.org/licenses/LICENSE-2.0</url>
|
||||
<comments>
|
||||
Copyright 2010 the original author or authors.
|
||||
<name>Spring Data MongoDB</name>
|
||||
<description>MongoDB support for Spring Data</description>
|
||||
<url>http://www.springsource.org/spring-data/mongodb</url>
|
||||
|
||||
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
|
||||
<parent>
|
||||
<groupId>org.springframework.data.build</groupId>
|
||||
<artifactId>spring-data-parent</artifactId>
|
||||
<version>1.0.4.RELEASE</version>
|
||||
<relativePath>../spring-data-build/parent/pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
<modules>
|
||||
<module>spring-data-mongodb</module>
|
||||
<module>spring-data-mongodb-cross-store</module>
|
||||
<module>spring-data-mongodb-log4j</module>
|
||||
<module>spring-data-mongodb-distribution</module>
|
||||
</modules>
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
<properties>
|
||||
<project.type>multi</project.type>
|
||||
<dist.id>spring-data-mongodb</dist.id>
|
||||
<springdata.commons>1.5.2.RELEASE</springdata.commons>
|
||||
<mongo>2.10.1</mongo>
|
||||
</properties>
|
||||
|
||||
<developers>
|
||||
<developer>
|
||||
<id>ogierke</id>
|
||||
<name>Oliver Gierke</name>
|
||||
<email>ogierke at vmware.com</email>
|
||||
<organization>SpringSource</organization>
|
||||
<organizationUrl>http://www.springsource.com</organizationUrl>
|
||||
<roles>
|
||||
<role>Project Lean</role>
|
||||
</roles>
|
||||
<timezone>+1</timezone>
|
||||
</developer>
|
||||
<developer>
|
||||
<id>trisberg</id>
|
||||
<name>Thomas Risberg</name>
|
||||
<email>trisberg at vmware.com</email>
|
||||
<organization>SpringSource</organization>
|
||||
<organizationUrl>http://www.springsource.com</organizationUrl>
|
||||
<roles>
|
||||
<role>Developer</role>
|
||||
</roles>
|
||||
<timezone>-5</timezone>
|
||||
</developer>
|
||||
<developer>
|
||||
<id>mpollack</id>
|
||||
<name>Mark Pollack</name>
|
||||
<email>mpollack at vmware.com</email>
|
||||
<organization>SpringSource</organization>
|
||||
<organizationUrl>http://www.springsource.com</organizationUrl>
|
||||
<roles>
|
||||
<role>Developer</role>
|
||||
</roles>
|
||||
<timezone>-5</timezone>
|
||||
</developer>
|
||||
<developer>
|
||||
<id>jbrisbin</id>
|
||||
<name>Jon Brisbin</name>
|
||||
<email>jbrisbin at vmware.com</email>
|
||||
<organization>SpringSource</organization>
|
||||
<organizationUrl>http://www.springsource.com</organizationUrl>
|
||||
<roles>
|
||||
<role>Developer</role>
|
||||
</roles>
|
||||
<timezone>-6</timezone>
|
||||
</developer>
|
||||
</developers>
|
||||
|
||||
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.
|
||||
</comments>
|
||||
</license>
|
||||
</licenses>
|
||||
<dependencies>
|
||||
<!-- MongoDB -->
|
||||
<dependency>
|
||||
<groupId>org.mongodb</groupId>
|
||||
<artifactId>mongo-java-driver</artifactId>
|
||||
<version>${mongo}</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<properties>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
<!-- dist.* properties are used by the antrun tasks below -->
|
||||
<dist.id>spring-data-mongo</dist.id>
|
||||
<dist.name>Spring Data Mongo</dist.name>
|
||||
<dist.key>SDMONGO</dist.key>
|
||||
<dist.version>${project.version}</dist.version>
|
||||
<dist.releaseType>snapshot</dist.releaseType>
|
||||
<dist.finalName>${dist.id}-${dist.version}</dist.finalName>
|
||||
<dist.fileName>${dist.finalName}.zip</dist.fileName>
|
||||
<dist.filePath>target/${dist.fileName}</dist.filePath>
|
||||
<dist.bucketName>dist.springframework.org</dist.bucketName>
|
||||
<!-- these properties should be in ~/.m2/settings.xml
|
||||
<dist.accessKey>s3 access key</dist.accessKey>
|
||||
<dist.secretKey>s3 secret key</dist.secretKey>
|
||||
-->
|
||||
</properties>
|
||||
|
||||
<build>
|
||||
<extensions>
|
||||
<extension>
|
||||
<groupId>org.springframework.build.aws</groupId>
|
||||
<artifactId>org.springframework.build.aws.maven</artifactId>
|
||||
<version>3.1.0.RELEASE</version>
|
||||
</extension>
|
||||
</extensions>
|
||||
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>com.agilejava.docbkx</groupId>
|
||||
<artifactId>docbkx-maven-plugin</artifactId>
|
||||
<!-- yes it really needs to be this (2.0.7) otherwise pdf generation from a clean build doesn't work -->
|
||||
<version>2.0.7</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<goals>
|
||||
<goal>generate-html</goal>
|
||||
<goal>generate-pdf</goal>
|
||||
</goals>
|
||||
<phase>pre-site</phase>
|
||||
</execution>
|
||||
</executions>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.docbook</groupId>
|
||||
<artifactId>docbook-xml</artifactId>
|
||||
<version>4.4</version>
|
||||
<scope>runtime</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
<configuration>
|
||||
<includes>index.xml</includes>
|
||||
<xincludeSupported>true</xincludeSupported>
|
||||
<foCustomization>${project.basedir}/src/docbkx/resources/xsl/fopdf.xsl</foCustomization>
|
||||
<htmlStylesheet>css/html.css</htmlStylesheet>
|
||||
<chunkedOutput>false</chunkedOutput>
|
||||
<htmlCustomization>${project.basedir}/src/docbkx/resources/xsl/html.xsl</htmlCustomization>
|
||||
<useExtensions>1</useExtensions>
|
||||
<highlightSource>1</highlightSource>
|
||||
<highlightDefaultLanguage />
|
||||
<!-- callouts -->
|
||||
<entities>
|
||||
<entity>
|
||||
<name>version</name>
|
||||
<value>${project.version}</value>
|
||||
</entity>
|
||||
</entities>
|
||||
<postProcess>
|
||||
<copy todir="${project.basedir}/target/site/reference">
|
||||
<fileset dir="${project.basedir}/target/docbkx">
|
||||
<include name="**/*.html" />
|
||||
<include name="**/*.pdf" />
|
||||
</fileset>
|
||||
</copy>
|
||||
<copy todir="${project.basedir}/target/site/reference/html">
|
||||
<fileset dir="${project.basedir}/src/docbkx/resources">
|
||||
<include name="**/*.css" />
|
||||
<include name="**/*.png" />
|
||||
<include name="**/*.gif" />
|
||||
<include name="**/*.jpg" />
|
||||
</fileset>
|
||||
</copy>
|
||||
<copy todir="${project.basedir}/target/site/reference/html">
|
||||
<fileset dir="${project.basedir}/src/docbkx/resources/images">
|
||||
<include name="*.png" />
|
||||
</fileset>
|
||||
</copy>
|
||||
<move file="${project.basedir}/target/site/reference/pdf/index.pdf" tofile="${project.basedir}/target/site/reference/pdf/spring-data-mongo-reference.pdf" failonerror="false" />
|
||||
</postProcess>
|
||||
</configuration>
|
||||
</plugin>
|
||||
|
||||
<plugin>
|
||||
<artifactId>maven-javadoc-plugin</artifactId>
|
||||
<version>2.5</version>
|
||||
<configuration>
|
||||
<aggregate>true</aggregate>
|
||||
<breakiterator>true</breakiterator>
|
||||
<header>Spring Data Document</header>
|
||||
<source>1.5</source>
|
||||
<quiet>true</quiet>
|
||||
<javadocDirectory>${project.basedir}/src/main/javadoc</javadocDirectory>
|
||||
<overview>${project.basedir}/src/main/javadoc/overview.html</overview>
|
||||
<stylesheetfile>${project.basedir}/src/main/javadoc/spring-javadoc.css</stylesheetfile>
|
||||
<!-- copies doc-files subdirectory which contains image resources -->
|
||||
<docfilessubdirs>true</docfilessubdirs>
|
||||
<links>
|
||||
<link>http://static.springframework.org/spring/docs/3.0.x/javadoc-api</link>
|
||||
<link>http://download.oracle.com/javase/1.5.0/docs/api</link>
|
||||
<link>http://api.mongodb.org/java/2.3</link>
|
||||
</links>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin><!--
|
||||
run `mvn package assembly:assembly` to trigger assembly creation.
|
||||
see http://www.sonatype.com/books/mvnref-book/reference/assemblies-set-dist-assemblies.html -->
|
||||
<artifactId>maven-assembly-plugin</artifactId>
|
||||
<version>2.2-beta-5</version>
|
||||
<inherited>false</inherited>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>distribution</id>
|
||||
<goals>
|
||||
<goal>single</goal>
|
||||
</goals>
|
||||
<phase>package</phase>
|
||||
<configuration>
|
||||
<descriptors>
|
||||
<descriptor>${project.basedir}/src/assembly/distribution.xml</descriptor>
|
||||
</descriptors>
|
||||
<appendAssemblyId>false</appendAssemblyId>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-antrun-plugin</artifactId>
|
||||
<version>1.4</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>upload-dist</id>
|
||||
<phase>deploy</phase>
|
||||
<configuration>
|
||||
<tasks>
|
||||
<ant antfile="${basedir}/src/ant/upload-dist.xml">
|
||||
<target name="upload-dist" />
|
||||
</ant>
|
||||
</tasks>
|
||||
</configuration>
|
||||
<goals>
|
||||
<goal>run</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.springframework.build</groupId>
|
||||
<artifactId>org.springframework.build.aws.ant</artifactId>
|
||||
<version>3.0.5.RELEASE</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>net.java.dev.jets3t</groupId>
|
||||
<artifactId>jets3t</artifactId>
|
||||
<version>0.7.2</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</plugin>
|
||||
</plugins>
|
||||
<!-- the name of this project is 'spring-data-mongo-dist';
|
||||
make sure the zip file is just 'spring-data-mongo'. -->
|
||||
<finalName>${dist.finalName}</finalName>
|
||||
</build>
|
||||
|
||||
<pluginRepositories>
|
||||
<!-- Necessary for the build extension -->
|
||||
<pluginRepository>
|
||||
<id>spring-plugins-release</id>
|
||||
<url>http://repo.springsource.org/plugins-release</url>
|
||||
</pluginRepository>
|
||||
</pluginRepositories>
|
||||
|
||||
<distributionManagement>
|
||||
<!-- see 'staging' profile for dry-run deployment settings -->
|
||||
<downloadUrl>http://www.springsource.com/spring-data</downloadUrl>
|
||||
<site>
|
||||
<id>static.springframework.org</id>
|
||||
<url>
|
||||
scp://static.springframework.org/var/www/domains/springframework.org/static/htdocs/spring-data/data-mongodb/snapshot-site
|
||||
</url>
|
||||
</site>
|
||||
<repository>
|
||||
<id>spring-milestone</id>
|
||||
<name>Spring Milestone Repository</name>
|
||||
<url>s3://maven.springframework.org/milestone</url>
|
||||
</repository>
|
||||
<snapshotRepository>
|
||||
<id>spring-snapshot</id>
|
||||
<name>Spring Snapshot Repository</name>
|
||||
<url>s3://maven.springframework.org/snapshot</url>
|
||||
</snapshotRepository>
|
||||
</distributionManagement>
|
||||
|
||||
<scm>
|
||||
<url>https://github.com/SpringSource/spring-data-mongodb</url>
|
||||
</scm>
|
||||
<repositories>
|
||||
<repository>
|
||||
<id>spring-libs-release</id>
|
||||
<url>http://repo.springsource.org/libs-release</url>
|
||||
</repository>
|
||||
</repositories>
|
||||
|
||||
</project>
|
||||
|
||||
@@ -1,139 +1,145 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<groupId>org.springframework.data</groupId>
|
||||
<artifactId>spring-data-mongodb-parent</artifactId>
|
||||
<version>1.1.3.BUILD-SNAPSHOT</version>
|
||||
<relativePath>../spring-data-mongodb-parent/pom.xml</relativePath>
|
||||
</parent>
|
||||
<artifactId>spring-data-mongodb-cross-store</artifactId>
|
||||
<name>Spring Data MongoDB Cross-store Persistence Support</name>
|
||||
<dependencies>
|
||||
|
||||
<!-- Spring -->
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-beans</artifactId>
|
||||
<version>${org.springframework.version.range}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-tx</artifactId>
|
||||
<version>${org.springframework.version.range}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-aspects</artifactId>
|
||||
<version>${org.springframework.version.range}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-orm</artifactId>
|
||||
<version>${org.springframework.version.range}</version>
|
||||
</dependency>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<parent>
|
||||
<groupId>org.springframework.data</groupId>
|
||||
<artifactId>spring-data-mongodb-parent</artifactId>
|
||||
<version>1.2.3.RELEASE</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
<artifactId>spring-data-mongodb-cross-store</artifactId>
|
||||
<name>Spring Data MongoDB - Cross-Store Persistence Support</name>
|
||||
|
||||
<properties>
|
||||
<jpa>1.0.0.Final</jpa>
|
||||
<hibernate>3.6.10.Final</hibernate>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
|
||||
<!-- Spring Data -->
|
||||
<dependency>
|
||||
<groupId>org.springframework.data</groupId>
|
||||
<artifactId>spring-data-commons-core</artifactId>
|
||||
<version>${data.commons.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.data</groupId>
|
||||
<artifactId>spring-data-mongodb</artifactId>
|
||||
<version>1.1.3.BUILD-SNAPSHOT</version>
|
||||
</dependency>
|
||||
<!-- Spring -->
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-beans</artifactId>
|
||||
<version>${spring}</version>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<groupId>commons-logging</groupId>
|
||||
<artifactId>commons-logging</artifactId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-tx</artifactId>
|
||||
<version>${spring}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-aspects</artifactId>
|
||||
<version>${spring}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-orm</artifactId>
|
||||
<version>${spring}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.aspectj</groupId>
|
||||
<artifactId>aspectjrt</artifactId>
|
||||
<version>${aspectj.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>cglib</groupId>
|
||||
<artifactId>cglib</artifactId>
|
||||
<version>2.2</version>
|
||||
</dependency>
|
||||
<!-- Spring Data -->
|
||||
<dependency>
|
||||
<groupId>org.springframework.data</groupId>
|
||||
<artifactId>spring-data-mongodb</artifactId>
|
||||
<version>1.2.3.RELEASE</version>
|
||||
</dependency>
|
||||
|
||||
<!-- JPA -->
|
||||
<dependency>
|
||||
<groupId>org.hibernate.javax.persistence</groupId>
|
||||
<artifactId>hibernate-jpa-2.0-api</artifactId>
|
||||
<version>1.0.0.Final</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.aspectj</groupId>
|
||||
<artifactId>aspectjrt</artifactId>
|
||||
<version>${aspectj}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>cglib</groupId>
|
||||
<artifactId>cglib</artifactId>
|
||||
<version>2.2</version>
|
||||
</dependency>
|
||||
|
||||
<!-- For Tests -->
|
||||
<dependency>
|
||||
<groupId>org.hibernate</groupId>
|
||||
<artifactId>hibernate-entitymanager</artifactId>
|
||||
<version>3.5.5-Final</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>hsqldb</groupId>
|
||||
<artifactId>hsqldb</artifactId>
|
||||
<version>1.8.0.10</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>javax.validation</groupId>
|
||||
<artifactId>validation-api</artifactId>
|
||||
<version>1.0.0.GA</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.hibernate</groupId>
|
||||
<artifactId>hibernate-validator</artifactId>
|
||||
<version>4.0.2.GA</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<!-- JPA -->
|
||||
<dependency>
|
||||
<groupId>org.hibernate.javax.persistence</groupId>
|
||||
<artifactId>hibernate-jpa-2.0-api</artifactId>
|
||||
<version>${jpa}</version>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
<!-- For Tests -->
|
||||
<dependency>
|
||||
<groupId>org.hibernate</groupId>
|
||||
<artifactId>hibernate-entitymanager</artifactId>
|
||||
<version>${hibernate}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>hsqldb</groupId>
|
||||
<artifactId>hsqldb</artifactId>
|
||||
<version>1.8.0.10</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>javax.validation</groupId>
|
||||
<artifactId>validation-api</artifactId>
|
||||
<version>1.0.0.GA</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.hibernate</groupId>
|
||||
<artifactId>hibernate-validator</artifactId>
|
||||
<version>4.0.2.GA</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.codehaus.mojo</groupId>
|
||||
<artifactId>aspectj-maven-plugin</artifactId>
|
||||
<version>1.2</version>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.aspectj</groupId>
|
||||
<artifactId>aspectjrt</artifactId>
|
||||
<version>${aspectj.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.aspectj</groupId>
|
||||
<artifactId>aspectjtools</artifactId>
|
||||
<version>${aspectj.version}</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
<executions>
|
||||
<execution>
|
||||
<goals>
|
||||
<goal>compile</goal>
|
||||
<goal>test-compile</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
<configuration>
|
||||
<outxml>true</outxml>
|
||||
<aspectLibraries>
|
||||
<aspectLibrary>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-aspects</artifactId>
|
||||
</aspectLibrary>
|
||||
<!-- <aspectLibrary>
|
||||
<groupId>org.springframework.data</groupId>
|
||||
<artifactId>spring-data-commons-aspects</artifactId>
|
||||
</aspectLibrary> -->
|
||||
</aspectLibraries>
|
||||
<source>1.5</source>
|
||||
<target>1.5</target>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.codehaus.mojo</groupId>
|
||||
<artifactId>aspectj-maven-plugin</artifactId>
|
||||
<version>1.4</version>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.aspectj</groupId>
|
||||
<artifactId>aspectjrt</artifactId>
|
||||
<version>${aspectj}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.aspectj</groupId>
|
||||
<artifactId>aspectjtools</artifactId>
|
||||
<version>${aspectj}</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
<executions>
|
||||
<execution>
|
||||
<goals>
|
||||
<goal>compile</goal>
|
||||
<goal>test-compile</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
<configuration>
|
||||
<outxml>true</outxml>
|
||||
<aspectLibraries>
|
||||
<aspectLibrary>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-aspects</artifactId>
|
||||
</aspectLibrary>
|
||||
</aspectLibraries>
|
||||
<source>${source.level}</source>
|
||||
<target>${source.level}</target>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
</project>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2011 the original author or authors.
|
||||
* 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.
|
||||
@@ -17,8 +17,8 @@ package org.springframework.data.mongodb.crossstore;
|
||||
|
||||
import javax.persistence.EntityManagerFactory;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.dao.DataAccessException;
|
||||
import org.springframework.dao.DataAccessResourceFailureException;
|
||||
import org.springframework.dao.DataIntegrityViolationException;
|
||||
@@ -34,6 +34,10 @@ import com.mongodb.DBCollection;
|
||||
import com.mongodb.DBObject;
|
||||
import com.mongodb.MongoException;
|
||||
|
||||
/**
|
||||
* @author Thomas Risberg
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
public class MongoChangeSetPersister implements ChangeSetPersister<Object> {
|
||||
|
||||
private static final String ENTITY_CLASS = "_entity_class";
|
||||
@@ -44,7 +48,7 @@ public class MongoChangeSetPersister implements ChangeSetPersister<Object> {
|
||||
|
||||
private static final String ENTITY_FIELD_CLASS = "_entity_field_class";
|
||||
|
||||
protected final Log log = LogFactory.getLog(getClass());
|
||||
protected final Logger log = LoggerFactory.getLogger(getClass());
|
||||
|
||||
private MongoTemplate mongoTemplate;
|
||||
|
||||
@@ -58,6 +62,10 @@ public class MongoChangeSetPersister implements ChangeSetPersister<Object> {
|
||||
this.entityManagerFactory = entityManagerFactory;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.crossstore.ChangeSetPersister#getPersistentState(java.lang.Class, java.lang.Object, org.springframework.data.crossstore.ChangeSet)
|
||||
*/
|
||||
public void getPersistentState(Class<? extends ChangeSetBacked> entityClass, Object id, final ChangeSet changeSet)
|
||||
throws DataAccessException, NotFoundException {
|
||||
|
||||
@@ -100,6 +108,10 @@ public class MongoChangeSetPersister implements ChangeSetPersister<Object> {
|
||||
});
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.crossstore.ChangeSetPersister#getPersistentId(org.springframework.data.crossstore.ChangeSetBacked, org.springframework.data.crossstore.ChangeSet)
|
||||
*/
|
||||
public Object getPersistentId(ChangeSetBacked entity, ChangeSet cs) throws DataAccessException {
|
||||
log.debug("getPersistentId called on " + entity);
|
||||
if (entityManagerFactory == null) {
|
||||
@@ -109,6 +121,10 @@ public class MongoChangeSetPersister implements ChangeSetPersister<Object> {
|
||||
return o;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.crossstore.ChangeSetPersister#persistState(org.springframework.data.crossstore.ChangeSetBacked, org.springframework.data.crossstore.ChangeSet)
|
||||
*/
|
||||
public Object persistState(ChangeSetBacked entity, ChangeSet cs) throws DataAccessException {
|
||||
if (cs == null) {
|
||||
log.debug("Flush: changeset was null, nothing to flush.");
|
||||
@@ -169,8 +185,13 @@ public class MongoChangeSetPersister implements ChangeSetPersister<Object> {
|
||||
return 0L;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the collection the given entity type shall be persisted to.
|
||||
*
|
||||
* @param entityClass must not be {@literal null}.
|
||||
* @return
|
||||
*/
|
||||
private String getCollectionNameForEntity(Class<? extends ChangeSetBacked> entityClass) {
|
||||
return ClassUtils.getQualifiedName(entityClass);
|
||||
return mongoTemplate.getCollectionName(entityClass);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -21,13 +21,12 @@ import javax.persistence.EntityManager;
|
||||
import javax.persistence.Transient;
|
||||
import javax.persistence.Entity;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.aspectj.lang.JoinPoint;
|
||||
import org.aspectj.lang.reflect.FieldSignature;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.dao.DataAccessException;
|
||||
|
||||
import org.springframework.data.mongodb.crossstore.RelatedDocument;
|
||||
import org.springframework.data.mongodb.crossstore.DocumentBacked;
|
||||
import org.springframework.data.crossstore.ChangeSetBackedTransactionSynchronization;
|
||||
@@ -44,7 +43,7 @@ import org.springframework.transaction.support.TransactionSynchronizationManager
|
||||
*/
|
||||
public aspect MongoDocumentBacking {
|
||||
|
||||
private static final Log LOGGER = LogFactory.getLog(MongoDocumentBacking.class);
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger(MongoDocumentBacking.class);
|
||||
|
||||
// Aspect shared config
|
||||
private ChangeSetPersister<Object> changeSetPersister;
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
/**
|
||||
* Infrastructure for Spring Data's MongoDB cross store support.
|
||||
*/
|
||||
package org.springframework.data.mongodb.crossstore;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2011 the original author or authors.
|
||||
* 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.
|
||||
@@ -18,7 +18,9 @@ package org.springframework.data.mongodb.crossstore;
|
||||
import javax.persistence.EntityManager;
|
||||
import javax.persistence.PersistenceContext;
|
||||
|
||||
import org.junit.After;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
@@ -26,7 +28,6 @@ import org.springframework.data.mongodb.core.MongoTemplate;
|
||||
import org.springframework.data.mongodb.crossstore.test.Address;
|
||||
import org.springframework.data.mongodb.crossstore.test.Person;
|
||||
import org.springframework.data.mongodb.crossstore.test.Resume;
|
||||
import org.springframework.test.annotation.Rollback;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
import org.springframework.transaction.PlatformTransactionManager;
|
||||
@@ -35,55 +36,76 @@ import org.springframework.transaction.annotation.Transactional;
|
||||
import org.springframework.transaction.support.TransactionCallback;
|
||||
import org.springframework.transaction.support.TransactionTemplate;
|
||||
|
||||
import com.mongodb.DBCollection;
|
||||
import com.mongodb.DBObject;
|
||||
|
||||
/**
|
||||
* Integration tests for MongoDB cross-store persistence (mainly {@link MongoChangeSetPersister}).
|
||||
*
|
||||
* @author Thomas Risberg
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
@ContextConfiguration(locations = "classpath:/META-INF/spring/applicationContext.xml")
|
||||
@ContextConfiguration("classpath:/META-INF/spring/applicationContext.xml")
|
||||
public class CrossStoreMongoTests {
|
||||
|
||||
@Autowired
|
||||
private MongoTemplate mongoTemplate;
|
||||
|
||||
private EntityManager entityManager;
|
||||
|
||||
@Autowired
|
||||
private PlatformTransactionManager transactionManager;
|
||||
MongoTemplate mongoTemplate;
|
||||
|
||||
@PersistenceContext
|
||||
public void setEntityManager(EntityManager entityManager) {
|
||||
this.entityManager = entityManager;
|
||||
EntityManager entityManager;
|
||||
|
||||
@Autowired
|
||||
PlatformTransactionManager transactionManager;
|
||||
TransactionTemplate txTemplate;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
|
||||
txTemplate = new TransactionTemplate(transactionManager);
|
||||
|
||||
clearData(Person.class);
|
||||
|
||||
Address address = new Address(12, "MAin St.", "Boston", "MA", "02101");
|
||||
|
||||
Resume resume = new Resume();
|
||||
resume.addEducation("Skanstulls High School, 1975");
|
||||
resume.addEducation("Univ. of Stockholm, 1980");
|
||||
resume.addJob("DiMark, DBA, 1990-2000");
|
||||
resume.addJob("VMware, Developer, 2007-");
|
||||
|
||||
final Person person = new Person("Thomas", 20);
|
||||
person.setAddress(address);
|
||||
person.setResume(resume);
|
||||
person.setId(1L);
|
||||
|
||||
txTemplate.execute(new TransactionCallback<Void>() {
|
||||
public Void doInTransaction(TransactionStatus status) {
|
||||
entityManager.persist(person);
|
||||
return null;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void clearData(String collectionName) {
|
||||
DBCollection col = this.mongoTemplate.getCollection(collectionName);
|
||||
if (col != null) {
|
||||
this.mongoTemplate.dropCollection(collectionName);
|
||||
}
|
||||
@After
|
||||
public void tearDown() {
|
||||
txTemplate.execute(new TransactionCallback<Void>() {
|
||||
public Void doInTransaction(TransactionStatus status) {
|
||||
entityManager.remove(entityManager.find(Person.class, 1L));
|
||||
return null;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void clearData(Class<?> domainType) {
|
||||
|
||||
String collectionName = mongoTemplate.getCollectionName(domainType);
|
||||
mongoTemplate.dropCollection(collectionName);
|
||||
}
|
||||
|
||||
@Test
|
||||
@Transactional
|
||||
@Rollback(false)
|
||||
public void testCreateJpaToMongoEntityRelationship() {
|
||||
clearData(Person.class.getName());
|
||||
Person p = new Person("Thomas", 20);
|
||||
Address a = new Address(12, "MAin St.", "Boston", "MA", "02101");
|
||||
p.setAddress(a);
|
||||
Resume r = new Resume();
|
||||
r.addEducation("Skanstulls High School, 1975");
|
||||
r.addEducation("Univ. of Stockholm, 1980");
|
||||
r.addJob("DiMark, DBA, 1990-2000");
|
||||
r.addJob("VMware, Developer, 2007-");
|
||||
p.setResume(r);
|
||||
p.setId(1L);
|
||||
entityManager.persist(p);
|
||||
}
|
||||
|
||||
@Test
|
||||
@Transactional
|
||||
@Rollback(false)
|
||||
public void testReadJpaToMongoEntityRelationship() {
|
||||
|
||||
Person found = entityManager.find(Person.class, 1L);
|
||||
Assert.assertNotNull(found);
|
||||
Assert.assertEquals(Long.valueOf(1), found.getId());
|
||||
@@ -91,15 +113,18 @@ public class CrossStoreMongoTests {
|
||||
Assert.assertEquals(Long.valueOf(1), found.getId());
|
||||
Assert.assertNotNull(found.getResume());
|
||||
Assert.assertEquals("DiMark, DBA, 1990-2000" + "; " + "VMware, Developer, 2007-", found.getResume().getJobs());
|
||||
found.getResume().addJob("SpringDeveloper.com, Consultant, 2005-2006");
|
||||
found.setAge(44);
|
||||
}
|
||||
|
||||
@Test
|
||||
@Transactional
|
||||
@Rollback(false)
|
||||
public void testUpdatedJpaToMongoEntityRelationship() {
|
||||
|
||||
Person found = entityManager.find(Person.class, 1L);
|
||||
found.setAge(44);
|
||||
found.getResume().addJob("SpringDeveloper.com, Consultant, 2005-2006");
|
||||
|
||||
entityManager.merge(found);
|
||||
|
||||
Assert.assertNotNull(found);
|
||||
Assert.assertEquals(Long.valueOf(1), found.getId());
|
||||
Assert.assertNotNull(found);
|
||||
@@ -111,14 +136,19 @@ public class CrossStoreMongoTests {
|
||||
|
||||
@Test
|
||||
public void testMergeJpaEntityWithMongoDocument() {
|
||||
TransactionTemplate txTemplate = new TransactionTemplate(transactionManager);
|
||||
|
||||
final Person detached = entityManager.find(Person.class, 1L);
|
||||
entityManager.detach(detached);
|
||||
detached.getResume().addJob("TargetRx, Developer, 2000-2005");
|
||||
|
||||
Person merged = txTemplate.execute(new TransactionCallback<Person>() {
|
||||
public Person doInTransaction(TransactionStatus status) {
|
||||
return entityManager.merge(detached);
|
||||
Person result = entityManager.merge(detached);
|
||||
entityManager.flush();
|
||||
return result;
|
||||
}
|
||||
});
|
||||
|
||||
Assert.assertTrue(detached.getResume().getJobs().contains("TargetRx, Developer, 2000-2005"));
|
||||
Assert.assertTrue(merged.getResume().getJobs().contains("TargetRx, Developer, 2000-2005"));
|
||||
final Person updated = entityManager.find(Person.class, 1L);
|
||||
@@ -127,7 +157,7 @@ public class CrossStoreMongoTests {
|
||||
|
||||
@Test
|
||||
public void testRemoveJpaEntityWithMongoDocument() {
|
||||
TransactionTemplate txTemplate = new TransactionTemplate(transactionManager);
|
||||
|
||||
txTemplate.execute(new TransactionCallback<Person>() {
|
||||
public Person doInTransaction(TransactionStatus status) {
|
||||
Person p2 = new Person("Thomas", 20);
|
||||
@@ -154,8 +184,10 @@ public class CrossStoreMongoTests {
|
||||
return null;
|
||||
}
|
||||
});
|
||||
|
||||
boolean weFound3 = false;
|
||||
for (DBObject dbo : this.mongoTemplate.getCollection(Person.class.getName()).find()) {
|
||||
|
||||
for (DBObject dbo : this.mongoTemplate.getCollection(mongoTemplate.getCollectionName(Person.class)).find()) {
|
||||
Assert.assertTrue(!dbo.get("_entity_id").equals(2L));
|
||||
if (dbo.get("_entity_id").equals(3L)) {
|
||||
weFound3 = true;
|
||||
|
||||
18
spring-data-mongodb-cross-store/template.mf
Normal file
18
spring-data-mongodb-cross-store/template.mf
Normal file
@@ -0,0 +1,18 @@
|
||||
Bundle-SymbolicName: org.springframework.data.mongodb.crossstore
|
||||
Bundle-Name: Spring Data MongoDB Cross Store Support
|
||||
Bundle-Vendor: SpringSource
|
||||
Bundle-ManifestVersion: 2
|
||||
Import-Package:
|
||||
sun.reflect;version="0";resolution:=optional
|
||||
Export-Template:
|
||||
org.springframework.data.mongodb.crossstore.*;version="${project.version}"
|
||||
Import-Template:
|
||||
com.mongodb.*;version="0",
|
||||
javax.persistence.*;version="${jpa:[=.=.=,+1.0.0)}",
|
||||
org.aspectj.*;version="${aspectj:[1.0.0, 2.0.0)}",
|
||||
org.bson.*;version="0",
|
||||
org.slf4j.*;version="${slf4j:[=.=.=,+1.0.0)}",
|
||||
org.springframework.*;version="${spring30:[=.=.=.=,+1.0.0)}",
|
||||
org.springframework.data.*;version="${springdata.commons:[=.=.=.=,+1.0.0)}",
|
||||
org.springframework.data.mongodb.*;version="${project.version:[=.=.=.=,+1.0.0)}",
|
||||
org.w3c.dom.*;version="0"
|
||||
38
spring-data-mongodb-distribution/pom.xml
Normal file
38
spring-data-mongodb-distribution/pom.xml
Normal file
@@ -0,0 +1,38 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<artifactId>spring-data-mongodb-distribution</artifactId>
|
||||
|
||||
<packaging>pom</packaging>
|
||||
|
||||
<name>Spring Data MongoDB - Distribution</name>
|
||||
<description>Distribution build for Spring Data MongoDB</description>
|
||||
|
||||
<parent>
|
||||
<groupId>org.springframework.data</groupId>
|
||||
<artifactId>spring-data-mongodb-parent</artifactId>
|
||||
<version>1.2.3.RELEASE</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
<properties>
|
||||
<project.root>${basedir}/..</project.root>
|
||||
<dist.key>SDMONGO</dist.key>
|
||||
</properties>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-assembly-plugin</artifactId>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.codehaus.mojo</groupId>
|
||||
<artifactId>wagon-maven-plugin</artifactId>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
</project>
|
||||
@@ -32,7 +32,7 @@ An example log entry might look like:
|
||||
{
|
||||
"_id" : ObjectId("4d89341a8ef397e06940d5cd"),
|
||||
"applicationId" : "my.application",
|
||||
"name" : "org.springframework.data.mongodb.log4j.AppenderTest",
|
||||
"name" : "org.springframework.data.mongodb.log4j.MongoLog4jAppenderIntegrationTests",
|
||||
"level" : "DEBUG",
|
||||
"timestamp" : ISODate("2011-03-23T16:53:46.778Z"),
|
||||
"properties" : {
|
||||
|
||||
@@ -1,44 +1,30 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<groupId>org.springframework.data</groupId>
|
||||
<artifactId>spring-data-mongodb-parent</artifactId>
|
||||
<version>1.1.3.BUILD-SNAPSHOT</version>
|
||||
<relativePath>../spring-data-mongodb-parent/pom.xml</relativePath>
|
||||
</parent>
|
||||
<artifactId>spring-data-mongodb-log4j</artifactId>
|
||||
<name>Spring Data MongoDB Log4J Appender</name>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<parent>
|
||||
<groupId>org.springframework.data</groupId>
|
||||
<artifactId>spring-data-mongodb-parent</artifactId>
|
||||
<version>1.2.3.RELEASE</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
<properties>
|
||||
<log4j.version>1.2.16</log4j.version>
|
||||
</properties>
|
||||
<artifactId>spring-data-mongodb-log4j</artifactId>
|
||||
<name>Spring Data MongoDB - Log4J Appender</name>
|
||||
|
||||
<dependencies>
|
||||
<properties>
|
||||
<log4j>1.2.16</log4j>
|
||||
</properties>
|
||||
|
||||
<!-- MongoDB -->
|
||||
<dependency>
|
||||
<groupId>org.mongodb</groupId>
|
||||
<artifactId>mongo-java-driver</artifactId>
|
||||
<version>${mongo.version}</version>
|
||||
</dependency>
|
||||
<dependencies>
|
||||
|
||||
<!-- Logging -->
|
||||
<dependency>
|
||||
<groupId>log4j</groupId>
|
||||
<artifactId>log4j</artifactId>
|
||||
<version>${log4j.version}</version>
|
||||
</dependency>
|
||||
<!-- Logging -->
|
||||
<dependency>
|
||||
<groupId>log4j</groupId>
|
||||
<artifactId>log4j</artifactId>
|
||||
<version>${log4j}</version>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>com.springsource.bundlor</groupId>
|
||||
<artifactId>com.springsource.bundlor.maven</artifactId>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</dependencies>
|
||||
|
||||
</project>
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
/*
|
||||
* Copyright (c) 2011 by the original author(s).
|
||||
* 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
|
||||
* 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,7 +13,6 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.data.mongodb.log4j;
|
||||
|
||||
import java.net.UnknownHostException;
|
||||
@@ -21,188 +20,207 @@ import java.util.Arrays;
|
||||
import java.util.Calendar;
|
||||
import java.util.Map;
|
||||
|
||||
import com.mongodb.BasicDBList;
|
||||
import com.mongodb.BasicDBObject;
|
||||
import com.mongodb.DB;
|
||||
import com.mongodb.Mongo;
|
||||
import com.mongodb.WriteConcern;
|
||||
import org.apache.log4j.AppenderSkeleton;
|
||||
import org.apache.log4j.Level;
|
||||
import org.apache.log4j.MDC;
|
||||
import org.apache.log4j.PatternLayout;
|
||||
import org.apache.log4j.spi.LoggingEvent;
|
||||
|
||||
import com.mongodb.BasicDBList;
|
||||
import com.mongodb.BasicDBObject;
|
||||
import com.mongodb.DB;
|
||||
import com.mongodb.Mongo;
|
||||
import com.mongodb.WriteConcern;
|
||||
|
||||
/**
|
||||
* @author Jon Brisbin <jbrisbin@vmware.com>
|
||||
* Log4j appender writing log entries into a MongoDB instance.
|
||||
*
|
||||
* @author Jon Brisbin
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
public class MongoLog4jAppender extends AppenderSkeleton {
|
||||
|
||||
public static final String LEVEL = "level";
|
||||
public static final String NAME = "name";
|
||||
public static final String APP_ID = "applicationId";
|
||||
public static final String TIMESTAMP = "timestamp";
|
||||
public static final String PROPERTIES = "properties";
|
||||
public static final String TRACEBACK = "traceback";
|
||||
public static final String MESSAGE = "message";
|
||||
public static final String YEAR = "year";
|
||||
public static final String MONTH = "month";
|
||||
public static final String DAY = "day";
|
||||
public static final String HOUR = "hour";
|
||||
public static final String LEVEL = "level";
|
||||
public static final String NAME = "name";
|
||||
public static final String APP_ID = "applicationId";
|
||||
public static final String TIMESTAMP = "timestamp";
|
||||
public static final String PROPERTIES = "properties";
|
||||
public static final String TRACEBACK = "traceback";
|
||||
public static final String MESSAGE = "message";
|
||||
public static final String YEAR = "year";
|
||||
public static final String MONTH = "month";
|
||||
public static final String DAY = "day";
|
||||
public static final String HOUR = "hour";
|
||||
|
||||
protected String host = "localhost";
|
||||
protected int port = 27017;
|
||||
protected String database = "logs";
|
||||
protected String collectionPattern = "%c";
|
||||
protected PatternLayout collectionLayout = new PatternLayout(collectionPattern);
|
||||
protected String applicationId = System.getProperty("APPLICATION_ID", null);
|
||||
protected WriteConcern warnOrHigherWriteConcern = WriteConcern.SAFE;
|
||||
protected WriteConcern infoOrLowerWriteConcern = WriteConcern.NORMAL;
|
||||
protected Mongo mongo;
|
||||
protected DB db;
|
||||
protected String host = "localhost";
|
||||
protected int port = 27017;
|
||||
protected String database = "logs";
|
||||
protected String collectionPattern = "%c";
|
||||
protected PatternLayout collectionLayout = new PatternLayout(collectionPattern);
|
||||
protected String applicationId = System.getProperty("APPLICATION_ID", null);
|
||||
protected WriteConcern warnOrHigherWriteConcern = WriteConcern.SAFE;
|
||||
protected WriteConcern infoOrLowerWriteConcern = WriteConcern.NORMAL;
|
||||
protected Mongo mongo;
|
||||
protected DB db;
|
||||
|
||||
public MongoLog4jAppender() {
|
||||
}
|
||||
public MongoLog4jAppender() {
|
||||
}
|
||||
|
||||
public MongoLog4jAppender(boolean isActive) {
|
||||
super(isActive);
|
||||
}
|
||||
public MongoLog4jAppender(boolean isActive) {
|
||||
super(isActive);
|
||||
}
|
||||
|
||||
public String getHost() {
|
||||
return host;
|
||||
}
|
||||
public String getHost() {
|
||||
return host;
|
||||
}
|
||||
|
||||
public void setHost(String host) {
|
||||
this.host = host;
|
||||
}
|
||||
public void setHost(String host) {
|
||||
this.host = host;
|
||||
}
|
||||
|
||||
public int getPort() {
|
||||
return port;
|
||||
}
|
||||
public int getPort() {
|
||||
return port;
|
||||
}
|
||||
|
||||
public void setPort(int port) {
|
||||
this.port = port;
|
||||
}
|
||||
public void setPort(int port) {
|
||||
this.port = port;
|
||||
}
|
||||
|
||||
public String getDatabase() {
|
||||
return database;
|
||||
}
|
||||
public String getDatabase() {
|
||||
return database;
|
||||
}
|
||||
|
||||
public void setDatabase(String database) {
|
||||
this.database = database;
|
||||
}
|
||||
public void setDatabase(String database) {
|
||||
this.database = database;
|
||||
}
|
||||
|
||||
public String getCollectionPattern() {
|
||||
return collectionPattern;
|
||||
}
|
||||
public String getCollectionPattern() {
|
||||
return collectionPattern;
|
||||
}
|
||||
|
||||
public void setCollectionPattern(String collectionPattern) {
|
||||
this.collectionPattern = collectionPattern;
|
||||
this.collectionLayout = new PatternLayout(collectionPattern);
|
||||
}
|
||||
public void setCollectionPattern(String collectionPattern) {
|
||||
this.collectionPattern = collectionPattern;
|
||||
this.collectionLayout = new PatternLayout(collectionPattern);
|
||||
}
|
||||
|
||||
public String getApplicationId() {
|
||||
return applicationId;
|
||||
}
|
||||
public String getApplicationId() {
|
||||
return applicationId;
|
||||
}
|
||||
|
||||
public void setApplicationId(String applicationId) {
|
||||
this.applicationId = applicationId;
|
||||
}
|
||||
public void setApplicationId(String applicationId) {
|
||||
this.applicationId = applicationId;
|
||||
}
|
||||
|
||||
public void setWarnOrHigherWriteConcern(String wc) {
|
||||
this.warnOrHigherWriteConcern = WriteConcern.valueOf(wc);
|
||||
}
|
||||
public void setWarnOrHigherWriteConcern(String wc) {
|
||||
this.warnOrHigherWriteConcern = WriteConcern.valueOf(wc);
|
||||
}
|
||||
|
||||
public String getWarnOrHigherWriteConcern() {
|
||||
return warnOrHigherWriteConcern.toString();
|
||||
}
|
||||
public String getWarnOrHigherWriteConcern() {
|
||||
return warnOrHigherWriteConcern.toString();
|
||||
}
|
||||
|
||||
public String getInfoOrLowerWriteConcern() {
|
||||
return infoOrLowerWriteConcern.toString();
|
||||
}
|
||||
public String getInfoOrLowerWriteConcern() {
|
||||
return infoOrLowerWriteConcern.toString();
|
||||
}
|
||||
|
||||
public void setInfoOrLowerWriteConcern(String wc) {
|
||||
this.infoOrLowerWriteConcern = WriteConcern.valueOf(wc);
|
||||
}
|
||||
public void setInfoOrLowerWriteConcern(String wc) {
|
||||
this.infoOrLowerWriteConcern = WriteConcern.valueOf(wc);
|
||||
}
|
||||
|
||||
protected void connectToMongo() throws UnknownHostException {
|
||||
this.mongo = new Mongo(host, port);
|
||||
this.db = mongo.getDB(database);
|
||||
}
|
||||
protected void connectToMongo() throws UnknownHostException {
|
||||
this.mongo = new Mongo(host, port);
|
||||
this.db = mongo.getDB(database);
|
||||
}
|
||||
|
||||
@SuppressWarnings({"unchecked"})
|
||||
@Override
|
||||
protected void append(final LoggingEvent event) {
|
||||
if (null == db) {
|
||||
try {
|
||||
connectToMongo();
|
||||
} catch (UnknownHostException e) {
|
||||
throw new RuntimeException(e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.apache.log4j.AppenderSkeleton#append(org.apache.log4j.spi.LoggingEvent)
|
||||
*/
|
||||
@Override
|
||||
@SuppressWarnings({ "unchecked" })
|
||||
protected void append(final LoggingEvent event) {
|
||||
if (null == db) {
|
||||
try {
|
||||
connectToMongo();
|
||||
} catch (UnknownHostException e) {
|
||||
throw new RuntimeException(e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
|
||||
BasicDBObject dbo = new BasicDBObject();
|
||||
if (null != applicationId) {
|
||||
dbo.put(APP_ID, applicationId);
|
||||
MDC.put(APP_ID, applicationId);
|
||||
}
|
||||
dbo.put(NAME, event.getLogger().getName());
|
||||
dbo.put(LEVEL, event.getLevel().toString());
|
||||
Calendar tstamp = Calendar.getInstance();
|
||||
tstamp.setTimeInMillis(event.getTimeStamp());
|
||||
dbo.put(TIMESTAMP, tstamp.getTime());
|
||||
BasicDBObject dbo = new BasicDBObject();
|
||||
if (null != applicationId) {
|
||||
dbo.put(APP_ID, applicationId);
|
||||
MDC.put(APP_ID, applicationId);
|
||||
}
|
||||
dbo.put(NAME, event.getLogger().getName());
|
||||
dbo.put(LEVEL, event.getLevel().toString());
|
||||
Calendar tstamp = Calendar.getInstance();
|
||||
tstamp.setTimeInMillis(event.getTimeStamp());
|
||||
dbo.put(TIMESTAMP, tstamp.getTime());
|
||||
|
||||
// Copy properties into document
|
||||
Map<Object, Object> props = event.getProperties();
|
||||
if (null != props && props.size() > 0) {
|
||||
BasicDBObject propsDbo = new BasicDBObject();
|
||||
for (Map.Entry<Object, Object> entry : props.entrySet()) {
|
||||
propsDbo.put(entry.getKey().toString(), entry.getValue().toString());
|
||||
}
|
||||
dbo.put(PROPERTIES, propsDbo);
|
||||
}
|
||||
// Copy properties into document
|
||||
Map<Object, Object> props = event.getProperties();
|
||||
if (null != props && props.size() > 0) {
|
||||
BasicDBObject propsDbo = new BasicDBObject();
|
||||
for (Map.Entry<Object, Object> entry : props.entrySet()) {
|
||||
propsDbo.put(entry.getKey().toString(), entry.getValue().toString());
|
||||
}
|
||||
dbo.put(PROPERTIES, propsDbo);
|
||||
}
|
||||
|
||||
// Copy traceback info (if there is any) into the document
|
||||
String[] traceback = event.getThrowableStrRep();
|
||||
if (null != traceback && traceback.length > 0) {
|
||||
BasicDBList tbDbo = new BasicDBList();
|
||||
tbDbo.addAll(Arrays.asList(traceback));
|
||||
dbo.put(TRACEBACK, tbDbo);
|
||||
}
|
||||
// Copy traceback info (if there is any) into the document
|
||||
String[] traceback = event.getThrowableStrRep();
|
||||
if (null != traceback && traceback.length > 0) {
|
||||
BasicDBList tbDbo = new BasicDBList();
|
||||
tbDbo.addAll(Arrays.asList(traceback));
|
||||
dbo.put(TRACEBACK, tbDbo);
|
||||
}
|
||||
|
||||
// Put the rendered message into the document
|
||||
dbo.put(MESSAGE, event.getRenderedMessage());
|
||||
// Put the rendered message into the document
|
||||
dbo.put(MESSAGE, event.getRenderedMessage());
|
||||
|
||||
// Insert the document
|
||||
Calendar now = Calendar.getInstance();
|
||||
MDC.put(YEAR, now.get(Calendar.YEAR));
|
||||
MDC.put(MONTH, String.format("%1$02d", now.get(Calendar.MONTH) + 1));
|
||||
MDC.put(DAY, String.format("%1$02d", now.get(Calendar.DAY_OF_MONTH)));
|
||||
MDC.put(HOUR, String.format("%1$02d", now.get(Calendar.HOUR_OF_DAY)));
|
||||
// Insert the document
|
||||
Calendar now = Calendar.getInstance();
|
||||
MDC.put(YEAR, now.get(Calendar.YEAR));
|
||||
MDC.put(MONTH, String.format("%1$02d", now.get(Calendar.MONTH) + 1));
|
||||
MDC.put(DAY, String.format("%1$02d", now.get(Calendar.DAY_OF_MONTH)));
|
||||
MDC.put(HOUR, String.format("%1$02d", now.get(Calendar.HOUR_OF_DAY)));
|
||||
|
||||
String coll = collectionLayout.format(event);
|
||||
String coll = collectionLayout.format(event);
|
||||
|
||||
MDC.remove(YEAR);
|
||||
MDC.remove(MONTH);
|
||||
MDC.remove(DAY);
|
||||
MDC.remove(HOUR);
|
||||
if (null != applicationId) {
|
||||
MDC.remove(APP_ID);
|
||||
}
|
||||
MDC.remove(YEAR);
|
||||
MDC.remove(MONTH);
|
||||
MDC.remove(DAY);
|
||||
MDC.remove(HOUR);
|
||||
if (null != applicationId) {
|
||||
MDC.remove(APP_ID);
|
||||
}
|
||||
|
||||
WriteConcern wc;
|
||||
if (event.getLevel().isGreaterOrEqual(Level.WARN)) {
|
||||
wc = warnOrHigherWriteConcern;
|
||||
} else {
|
||||
wc = infoOrLowerWriteConcern;
|
||||
}
|
||||
db.getCollection(coll).insert(dbo, wc);
|
||||
}
|
||||
WriteConcern wc;
|
||||
if (event.getLevel().isGreaterOrEqual(Level.WARN)) {
|
||||
wc = warnOrHigherWriteConcern;
|
||||
} else {
|
||||
wc = infoOrLowerWriteConcern;
|
||||
}
|
||||
db.getCollection(coll).insert(dbo, wc);
|
||||
}
|
||||
|
||||
public void close() {
|
||||
mongo.close();
|
||||
}
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.apache.log4j.AppenderSkeleton#close()
|
||||
*/
|
||||
public void close() {
|
||||
|
||||
public boolean requiresLayout() {
|
||||
return true;
|
||||
}
|
||||
if (mongo != null) {
|
||||
mongo.close();
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.apache.log4j.AppenderSkeleton#requiresLayout()
|
||||
*/
|
||||
public boolean requiresLayout() {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
/**
|
||||
* Infrastructure for to use MongoDB as a logging sink.
|
||||
*/
|
||||
package org.springframework.data.mongodb.log4j;
|
||||
|
||||
@@ -1,75 +0,0 @@
|
||||
/*
|
||||
* 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
|
||||
*
|
||||
* 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.log4j;
|
||||
|
||||
import static org.hamcrest.Matchers.*;
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import java.net.UnknownHostException;
|
||||
import java.util.Calendar;
|
||||
|
||||
import com.mongodb.DB;
|
||||
import com.mongodb.DBCursor;
|
||||
import com.mongodb.Mongo;
|
||||
import org.apache.log4j.Logger;
|
||||
import org.apache.log4j.MDC;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
/**
|
||||
* @author Jon Brisbin <jbrisbin@vmware.com>
|
||||
*/
|
||||
public class AppenderTest {
|
||||
|
||||
private static final String NAME = AppenderTest.class.getName();
|
||||
private Logger log = Logger.getLogger(NAME);
|
||||
private Mongo mongo;
|
||||
private DB db;
|
||||
private String collection;
|
||||
|
||||
@Before
|
||||
public void setup() {
|
||||
try {
|
||||
mongo = new Mongo("localhost", 27017);
|
||||
db = mongo.getDB("logs");
|
||||
Calendar now = Calendar.getInstance();
|
||||
collection = String.valueOf(now.get(Calendar.YEAR)) + String.format("%1$02d", now.get(Calendar.MONTH) + 1);
|
||||
db.getCollection(collection).drop();
|
||||
} catch (UnknownHostException e) {
|
||||
throw new RuntimeException(e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testLogging() {
|
||||
log.debug("DEBUG message");
|
||||
log.info("INFO message");
|
||||
log.warn("WARN message");
|
||||
log.error("ERROR message");
|
||||
|
||||
DBCursor msgs = db.getCollection(collection).find();
|
||||
assertThat(msgs.count(), is(4));
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testProperties() {
|
||||
MDC.put("property", "one");
|
||||
log.debug("DEBUG message");
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,77 @@
|
||||
/*
|
||||
* 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.log4j;
|
||||
|
||||
import static org.hamcrest.Matchers.*;
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import java.util.Calendar;
|
||||
|
||||
import org.apache.log4j.Logger;
|
||||
import org.apache.log4j.MDC;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
import com.mongodb.DB;
|
||||
import com.mongodb.DBCursor;
|
||||
import com.mongodb.Mongo;
|
||||
|
||||
/**
|
||||
* Integration tests for {@link MongoLog4jAppender}.
|
||||
*
|
||||
* @author Jon Brisbin
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
public class MongoLog4jAppenderIntegrationTests {
|
||||
|
||||
static final String NAME = MongoLog4jAppenderIntegrationTests.class.getName();
|
||||
|
||||
Logger log = Logger.getLogger(NAME);
|
||||
Mongo mongo;
|
||||
DB db;
|
||||
String collection;
|
||||
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
|
||||
mongo = new Mongo("localhost", 27017);
|
||||
db = mongo.getDB("logs");
|
||||
|
||||
Calendar now = Calendar.getInstance();
|
||||
collection = String.valueOf(now.get(Calendar.YEAR)) + String.format("%1$02d", now.get(Calendar.MONTH) + 1);
|
||||
db.getCollection(collection).drop();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testLogging() {
|
||||
|
||||
log.debug("DEBUG message");
|
||||
log.info("INFO message");
|
||||
log.warn("WARN message");
|
||||
log.error("ERROR message");
|
||||
|
||||
DBCursor msgs = db.getCollection(collection).find();
|
||||
|
||||
assertThat(msgs.count(), is(4));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testProperties() {
|
||||
|
||||
MDC.put("property", "one");
|
||||
log.debug("DEBUG message");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
/*
|
||||
* 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.log4j;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
/**
|
||||
* Unit tests for {@link MongoLog4jAppender}.
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
public class MongoLog4jAppenderUnitTests {
|
||||
|
||||
/**
|
||||
* @see DATAMONGO-641
|
||||
*/
|
||||
@Test
|
||||
public void closesWithoutMongoInstancePresent() {
|
||||
new MongoLog4jAppender().close();
|
||||
}
|
||||
}
|
||||
@@ -10,11 +10,4 @@ log4j.appender.stdout.collectionPattern = %X{year}%X{month}
|
||||
log4j.appender.stdout.applicationId = my.application
|
||||
log4j.appender.stdout.warnOrHigherWriteConcern = FSYNC_SAFE
|
||||
|
||||
log4j.category.org.apache.activemq=ERROR
|
||||
log4j.category.org.springframework.batch=DEBUG
|
||||
log4j.category.org.springframework.data.document.mongodb=DEBUG
|
||||
log4j.category.org.springframework.transaction=INFO
|
||||
|
||||
log4j.category.org.hibernate.SQL=DEBUG
|
||||
# for debugging datasource initialization
|
||||
# log4j.category.test.jdbc=DEBUG
|
||||
log4j.category.org.springframework.data.mongodb=DEBUG
|
||||
|
||||
@@ -5,6 +5,5 @@ Bundle-ManifestVersion: 2
|
||||
Import-Package:
|
||||
sun.reflect;version="0";resolution:=optional
|
||||
Import-Template:
|
||||
com.mongodb.*;version="${mongo.version:[=.=,+1.0.0)}",
|
||||
org.apache.log4j.*;version="[1.2.15, 2.0.0)",
|
||||
org.apache.log4j.spi.*;version="[1.2.15, 2.0.0)"
|
||||
com.mongodb.*;version="${mongo:[=.=,+1.0.0)}",
|
||||
org.apache.log4j.*;version="${log4j:[=.=.=,+1.0.0)}"
|
||||
|
||||
@@ -1,356 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<groupId>org.springframework.data</groupId>
|
||||
<artifactId>spring-data-mongodb-parent</artifactId>
|
||||
<name>Spring Data MongoDB Parent</name>
|
||||
<description>Spring Data project for MongoDB</description>
|
||||
<url>http://www.springsource.org/spring-data/mongodb</url>
|
||||
<version>1.1.3.BUILD-SNAPSHOT</version>
|
||||
<packaging>pom</packaging>
|
||||
|
||||
<developers>
|
||||
<developer>
|
||||
<id>trisberg</id>
|
||||
<name>Thomas Risberg</name>
|
||||
<email>trisberg at vmware.com</email>
|
||||
<organization>SpringSource</organization>
|
||||
<organizationUrl>http://www.SpringSource.com</organizationUrl>
|
||||
<roles>
|
||||
<role>Project Admin</role>
|
||||
<role>Developer</role>
|
||||
</roles>
|
||||
<timezone>-5</timezone>
|
||||
</developer>
|
||||
<developer>
|
||||
<id>mpollack</id>
|
||||
<name>Mark Pollack</name>
|
||||
<email>mpollack at vmware.com</email>
|
||||
<organization>SpringSource</organization>
|
||||
<organizationUrl>http://www.SpringSource.com</organizationUrl>
|
||||
<roles>
|
||||
<role>Project Admin</role>
|
||||
<role>Developer</role>
|
||||
</roles>
|
||||
<timezone>-5</timezone>
|
||||
</developer>
|
||||
<developer>
|
||||
<id>ogierke</id>
|
||||
<name>Oliver Gierke</name>
|
||||
<email>ogierke at vmware.com</email>
|
||||
<organization>SpringSource</organization>
|
||||
<organizationUrl>http://www.springsource.com</organizationUrl>
|
||||
<roles>
|
||||
<role>Developer</role>
|
||||
</roles>
|
||||
<timezone>+1</timezone>
|
||||
</developer>
|
||||
<developer>
|
||||
<id>jbrisbin</id>
|
||||
<name>Jon Brisbin</name>
|
||||
<email>jbrisbin at vmware.com</email>
|
||||
<organization>SpringSource</organization>
|
||||
<organizationUrl>http://www.springsource.com</organizationUrl>
|
||||
<roles>
|
||||
<role>Developer</role>
|
||||
</roles>
|
||||
<timezone>-6</timezone>
|
||||
</developer>
|
||||
</developers>
|
||||
|
||||
<licenses>
|
||||
<license>
|
||||
<name>Apache License, Version 2.0</name>
|
||||
<url>http://www.apache.org/licenses/LICENSE-2.0</url>
|
||||
<comments>
|
||||
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.
|
||||
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.
|
||||
</comments>
|
||||
</license>
|
||||
</licenses>
|
||||
|
||||
<properties>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
<!-- versions for commonly-used dependencies -->
|
||||
<mongo.version>2.9.3</mongo.version>
|
||||
<junit.version>4.10</junit.version>
|
||||
<logback.version>1.0.6</logback.version>
|
||||
<org.mockito.version>1.9.0</org.mockito.version>
|
||||
<org.slf4j.version>1.6.1</org.slf4j.version>
|
||||
<org.codehaus.jackson.version>1.6.1</org.codehaus.jackson.version>
|
||||
<org.springframework.version.30>3.0.7.RELEASE</org.springframework.version.30>
|
||||
<org.springframework.version.range>3.1.2.RELEASE</org.springframework.version.range>
|
||||
<data.commons.version>1.4.1.RELEASE</data.commons.version>
|
||||
<aspectj.version>1.6.11.RELEASE</aspectj.version>
|
||||
<bundlor.failOnWarnings>true</bundlor.failOnWarnings>
|
||||
</properties>
|
||||
|
||||
<distributionManagement>
|
||||
<!-- see 'staging' profile for dry-run deployment settings -->
|
||||
<downloadUrl>http://www.springsource.com/download/community
|
||||
</downloadUrl>
|
||||
<site>
|
||||
<id>static.springframework.org</id>
|
||||
<url>
|
||||
scp://static.springframework.org/var/www/domains/springframework.org/static/htdocs/spring-data/data-mongodb/snapshot-site
|
||||
</url>
|
||||
</site>
|
||||
<repository>
|
||||
<id>spring-milestone</id>
|
||||
<name>Spring Milestone Repository</name>
|
||||
<url>s3://maven.springframework.org/milestone</url>
|
||||
</repository>
|
||||
<snapshotRepository>
|
||||
<id>spring-snapshot</id>
|
||||
<name>Spring Snapshot Repository</name>
|
||||
<url>s3://maven.springframework.org/snapshot</url>
|
||||
</snapshotRepository>
|
||||
</distributionManagement>
|
||||
|
||||
<dependencies>
|
||||
|
||||
<!-- Test dependencies -->
|
||||
<dependency>
|
||||
<groupId>org.hamcrest</groupId>
|
||||
<artifactId>hamcrest-library</artifactId>
|
||||
<version>1.2.1</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>junit</groupId>
|
||||
<artifactId>junit-dep</artifactId>
|
||||
<version>${junit.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.mockito</groupId>
|
||||
<artifactId>mockito-core</artifactId>
|
||||
<version>${org.mockito.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>joda-time</groupId>
|
||||
<artifactId>joda-time</artifactId>
|
||||
<version>1.6</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>slf4j-api</artifactId>
|
||||
<version>${org.slf4j.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>jcl-over-slf4j</artifactId>
|
||||
<version>${org.slf4j.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>jul-to-slf4j</artifactId>
|
||||
<version>${org.slf4j.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>ch.qos.logback</groupId>
|
||||
<artifactId>logback-classic</artifactId>
|
||||
<version>${logback.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-test</artifactId>
|
||||
<version>${org.springframework.version.range}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<extensions>
|
||||
<extension>
|
||||
<!--
|
||||
available only in the springframework maven repository. see
|
||||
<repositories> section below
|
||||
-->
|
||||
<groupId>org.springframework.build.aws</groupId>
|
||||
<artifactId>org.springframework.build.aws.maven</artifactId>
|
||||
<version>3.1.0.RELEASE</version>
|
||||
</extension>
|
||||
</extensions>
|
||||
<resources>
|
||||
<resource>
|
||||
<directory>${project.basedir}/src/main/java</directory>
|
||||
<includes>
|
||||
<include>**/*</include>
|
||||
</includes>
|
||||
<excludes>
|
||||
<exclude>**/*.java</exclude>
|
||||
</excludes>
|
||||
</resource>
|
||||
<resource>
|
||||
<directory>${project.basedir}/src/main/resources</directory>
|
||||
<includes>
|
||||
<include>**/*</include>
|
||||
</includes>
|
||||
</resource>
|
||||
</resources>
|
||||
<testResources>
|
||||
<testResource>
|
||||
<directory>${project.basedir}/src/test/java</directory>
|
||||
<includes>
|
||||
<include>**/*</include>
|
||||
</includes>
|
||||
<excludes>
|
||||
<exclude>**/*.java</exclude>
|
||||
</excludes>
|
||||
</testResource>
|
||||
<testResource>
|
||||
<directory>${project.basedir}/src/test/resources</directory>
|
||||
<includes>
|
||||
<include>**/*</include>
|
||||
</includes>
|
||||
<excludes>
|
||||
<exclude>**/*.java</exclude>
|
||||
</excludes>
|
||||
</testResource>
|
||||
</testResources>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<version>2.5.1</version>
|
||||
<configuration>
|
||||
<source>1.5</source>
|
||||
<target>1.5</target>
|
||||
<compilerArgument>-Xlint:-path</compilerArgument>
|
||||
<showWarnings>true</showWarnings>
|
||||
<showDeprecation>false</showDeprecation>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-jar-plugin</artifactId>
|
||||
<version>2.3.1</version>
|
||||
<configuration>
|
||||
<useDefaultManifestFile>true</useDefaultManifestFile>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-surefire-plugin</artifactId>
|
||||
<version>2.12</version>
|
||||
<configuration>
|
||||
<useFile>false</useFile>
|
||||
<includes>
|
||||
<include>**/*Tests.java</include>
|
||||
</includes>
|
||||
<excludes>
|
||||
<exclude>**/PerformanceTests.java</exclude>
|
||||
</excludes>
|
||||
<junitArtifactName>junit:junit-dep</junitArtifactName>
|
||||
<systemPropertyVariables>
|
||||
<java.util.logging.config.file>src/test/resources/logging.properties</java.util.logging.config.file>
|
||||
</systemPropertyVariables>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<artifactId>maven-source-plugin</artifactId>
|
||||
<version>2.1.2</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>attach-sources</id>
|
||||
<goals>
|
||||
<goal>jar</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
<pluginManagement>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<!--
|
||||
configures the springsource bundlor plugin, which generates
|
||||
OSGI-compatible MANIFEST.MF files during the 'compile' phase of
|
||||
the maven build. this plugin is declared within the
|
||||
pluginManagement section because not every module that inherits
|
||||
from this pom needs bundlor's services, e.g.:
|
||||
spring-integration-samples and all its children. for this reason,
|
||||
all modules that wish to use bundlor must declare it explicitly.
|
||||
it is not necessary to specify the <version> or <configuration>
|
||||
sections, but groupId and artifactId are required. see
|
||||
http://static.springsource.org/s2-bundlor/1.0.x/user-guide/html/ch04s03.html
|
||||
for more info
|
||||
-->
|
||||
<groupId>com.springsource.bundlor</groupId>
|
||||
<artifactId>com.springsource.bundlor.maven</artifactId>
|
||||
<version>1.0.0.RELEASE</version>
|
||||
<configuration>
|
||||
<failOnWarnings>${bundlor.failOnWarnings}</failOnWarnings>
|
||||
</configuration>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>bundlor</id>
|
||||
<goals>
|
||||
<goal>bundlor</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</pluginManagement>
|
||||
</build>
|
||||
<pluginRepositories>
|
||||
<pluginRepository>
|
||||
<id>spring-plugins-release</id>
|
||||
<url>http://repo.springsource.org/plugins-release</url>
|
||||
</pluginRepository>
|
||||
<pluginRepository>
|
||||
<id>querydsl</id>
|
||||
<url>http://source.mysema.com/maven2/releases</url>
|
||||
</pluginRepository>
|
||||
</pluginRepositories>
|
||||
<repositories>
|
||||
<repository>
|
||||
<id>spring-libs-snapshot</id>
|
||||
<url>http://repo.springsource.org/libs-snapshot</url>
|
||||
</repository>
|
||||
</repositories>
|
||||
<reporting>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<!--
|
||||
significantly speeds up the 'Dependencies' report during site
|
||||
creation see
|
||||
http://old.nabble.com/Skipping-dependency-report-during-Maven2-site-generation-td20116761.html
|
||||
-->
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-project-info-reports-plugin</artifactId>
|
||||
<version>2.1</version>
|
||||
<configuration>
|
||||
<dependencyLocationsEnabled>false</dependencyLocationsEnabled>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</reporting>
|
||||
<scm>
|
||||
<url>https://github.com/SpringSource/spring-data-mongodb</url>
|
||||
</scm>
|
||||
</project>
|
||||
@@ -1,78 +1,80 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<artifactId>spring-data-mongodb</artifactId>
|
||||
|
||||
<name>Spring Data MongoDB - Core</name>
|
||||
<description>MongoDB support for Spring Data</description>
|
||||
|
||||
<parent>
|
||||
<groupId>org.springframework.data</groupId>
|
||||
<artifactId>spring-data-mongodb-parent</artifactId>
|
||||
<version>1.1.3.BUILD-SNAPSHOT</version>
|
||||
<relativePath>../spring-data-mongodb-parent/pom.xml</relativePath>
|
||||
<version>1.2.3.RELEASE</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
<artifactId>spring-data-mongodb</artifactId>
|
||||
<name>Spring Data MongoDB</name>
|
||||
|
||||
<properties>
|
||||
<querydsl.version>2.8.2</querydsl.version>
|
||||
<cdi.version>1.0</cdi.version>
|
||||
<validation.version>1.0.0.GA</validation.version>
|
||||
<webbeans.version>1.1.3</webbeans.version>
|
||||
<validation>1.0.0.GA</validation>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
|
||||
|
||||
<!-- Spring -->
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-tx</artifactId>
|
||||
<version>${org.springframework.version.range}</version>
|
||||
<version>${spring}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-context</artifactId>
|
||||
<version>${org.springframework.version.range}</version>
|
||||
<version>${spring}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-beans</artifactId>
|
||||
<version>${org.springframework.version.range}</version>
|
||||
<version>${spring}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-core</artifactId>
|
||||
<version>${org.springframework.version.range}</version>
|
||||
<version>${spring}</version>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<groupId>commons-logging</groupId>
|
||||
<artifactId>commons-logging</artifactId>
|
||||
</exclusion>
|
||||
<groupId>commons-logging</groupId>
|
||||
<artifactId>commons-logging</artifactId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-expression</artifactId>
|
||||
<version>${org.springframework.version.range}</version>
|
||||
<version>${spring}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- Spring Data -->
|
||||
<dependency>
|
||||
<groupId>org.springframework.data</groupId>
|
||||
<artifactId>spring-data-commons-core</artifactId>
|
||||
<version>${data.commons.version}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- MongoDB -->
|
||||
<dependency>
|
||||
<groupId>org.mongodb</groupId>
|
||||
<artifactId>mongo-java-driver</artifactId>
|
||||
<version>${mongo.version}</version>
|
||||
<dependency>
|
||||
<groupId>${project.groupId}</groupId>
|
||||
<artifactId>spring-data-commons</artifactId>
|
||||
<version>${springdata.commons}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.mysema.querydsl</groupId>
|
||||
<artifactId>querydsl-mongodb</artifactId>
|
||||
<version>${querydsl.version}</version>
|
||||
<version>${querydsl}</version>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.mysema.querydsl</groupId>
|
||||
<artifactId>querydsl-apt</artifactId>
|
||||
<version>${querydsl}</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>javax.annotation</groupId>
|
||||
<artifactId>jsr250-api</artifactId>
|
||||
@@ -84,7 +86,7 @@
|
||||
<dependency>
|
||||
<groupId>javax.enterprise</groupId>
|
||||
<artifactId>cdi-api</artifactId>
|
||||
<version>${cdi.version}</version>
|
||||
<version>${cdi}</version>
|
||||
<scope>provided</scope>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
@@ -92,14 +94,14 @@
|
||||
<dependency>
|
||||
<groupId>javax.el</groupId>
|
||||
<artifactId>el-api</artifactId>
|
||||
<version>${cdi.version}</version>
|
||||
<version>${cdi}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.apache.openwebbeans.test</groupId>
|
||||
<artifactId>cditest-owb</artifactId>
|
||||
<version>${webbeans.version}</version>
|
||||
<version>${webbeans}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
@@ -114,7 +116,7 @@
|
||||
<dependency>
|
||||
<groupId>javax.validation</groupId>
|
||||
<artifactId>validation-api</artifactId>
|
||||
<version>${validation.version}</version>
|
||||
<version>${validation}</version>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
|
||||
@@ -124,39 +126,18 @@
|
||||
<version>4.2.0.Final</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
|
||||
<dependency>
|
||||
<groupId>joda-time</groupId>
|
||||
<artifactId>joda-time</artifactId>
|
||||
<version>${jodatime}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
<profiles>
|
||||
<profile>
|
||||
<id>performance-tests</id>
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-surefire-plugin</artifactId>
|
||||
<version>2.8</version>
|
||||
<configuration>
|
||||
<includes>
|
||||
<include>**/PerformanceTests.java</include>
|
||||
</includes>
|
||||
<excludes>
|
||||
<exclude>none</exclude>
|
||||
</excludes>
|
||||
<junitArtifactName>junit:junit-dep</junitArtifactName>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</profile>
|
||||
</profiles>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>com.springsource.bundlor</groupId>
|
||||
<artifactId>com.springsource.bundlor.maven</artifactId>
|
||||
</plugin>
|
||||
|
||||
<plugin>
|
||||
<groupId>com.mysema.maven</groupId>
|
||||
@@ -166,7 +147,7 @@
|
||||
<dependency>
|
||||
<groupId>com.mysema.querydsl</groupId>
|
||||
<artifactId>querydsl-apt</artifactId>
|
||||
<version>${querydsl.version}</version>
|
||||
<version>${querydsl}</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
<executions>
|
||||
@@ -182,7 +163,25 @@
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-surefire-plugin</artifactId>
|
||||
<version>2.12</version>
|
||||
<configuration>
|
||||
<useFile>false</useFile>
|
||||
<includes>
|
||||
<include>**/*Tests.java</include>
|
||||
</includes>
|
||||
<excludes>
|
||||
<exclude>**/PerformanceTests.java</exclude>
|
||||
</excludes>
|
||||
<systemPropertyVariables>
|
||||
<java.util.logging.config.file>src/test/resources/logging.properties</java.util.logging.config.file>
|
||||
</systemPropertyVariables>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
|
||||
</project>
|
||||
|
||||
@@ -0,0 +1,72 @@
|
||||
/*
|
||||
* 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;
|
||||
|
||||
import org.springframework.dao.DataIntegrityViolationException;
|
||||
import org.springframework.data.mongodb.core.MongoActionOperation;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
import com.mongodb.WriteResult;
|
||||
|
||||
/**
|
||||
* Mongo-specific {@link DataIntegrityViolationException}.
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
public class MongoDataIntegrityViolationException extends DataIntegrityViolationException {
|
||||
|
||||
private static final long serialVersionUID = -186980521176764046L;
|
||||
|
||||
private final WriteResult writeResult;
|
||||
private final MongoActionOperation actionOperation;
|
||||
|
||||
/**
|
||||
* Creates a new {@link MongoDataIntegrityViolationException} using the given message and {@link WriteResult}.
|
||||
*
|
||||
* @param message the exception message
|
||||
* @param writeResult the {@link WriteResult} that causes the exception, must not be {@literal null}.
|
||||
* @param actionOperation the {@link MongoActionOperation} that caused the exception, must not be {@literal null}.
|
||||
*/
|
||||
public MongoDataIntegrityViolationException(String message, WriteResult writeResult,
|
||||
MongoActionOperation actionOperation) {
|
||||
|
||||
super(message);
|
||||
|
||||
Assert.notNull(writeResult, "WriteResult must not be null!");
|
||||
Assert.notNull(actionOperation, "MongoActionOperation must not be null!");
|
||||
|
||||
this.writeResult = writeResult;
|
||||
this.actionOperation = actionOperation;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the {@link WriteResult} that caused the exception.
|
||||
*
|
||||
* @return the writeResult
|
||||
*/
|
||||
public WriteResult getWriteResult() {
|
||||
return writeResult;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the {@link MongoActionOperation} in which the current exception occured.
|
||||
*
|
||||
* @return the actionOperation
|
||||
*/
|
||||
public MongoActionOperation getActionOperation() {
|
||||
return actionOperation;
|
||||
}
|
||||
}
|
||||
@@ -27,12 +27,15 @@ import org.springframework.core.convert.converter.Converter;
|
||||
import org.springframework.core.type.filter.AnnotationTypeFilter;
|
||||
import org.springframework.data.annotation.Persistent;
|
||||
import org.springframework.data.authentication.UserCredentials;
|
||||
import org.springframework.data.mapping.context.MappingContextIsNewStrategyFactory;
|
||||
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.Document;
|
||||
import org.springframework.data.mongodb.core.mapping.MongoMappingContext;
|
||||
import org.springframework.data.support.CachingIsNewStrategyFactory;
|
||||
import org.springframework.data.support.IsNewStrategyFactory;
|
||||
import org.springframework.util.ClassUtils;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
@@ -131,11 +134,21 @@ public abstract class AbstractMongoConfiguration {
|
||||
MongoMappingContext mappingContext = new MongoMappingContext();
|
||||
mappingContext.setInitialEntitySet(getInitialEntitySet());
|
||||
mappingContext.setSimpleTypeHolder(customConversions().getSimpleTypeHolder());
|
||||
mappingContext.initialize();
|
||||
|
||||
return mappingContext;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a {@link MappingContextIsNewStrategyFactory} wrapped into a {@link CachingIsNewStrategyFactory}.
|
||||
*
|
||||
* @return
|
||||
* @throws ClassNotFoundException
|
||||
*/
|
||||
@Bean
|
||||
public IsNewStrategyFactory isNewStrategyFactory() throws ClassNotFoundException {
|
||||
return new CachingIsNewStrategyFactory(new MappingContextIsNewStrategyFactory(mongoMappingContext()));
|
||||
}
|
||||
|
||||
/**
|
||||
* Register custom {@link Converter}s in a {@link CustomConversions} object if required. These
|
||||
* {@link CustomConversions} will be registered with the {@link #mappingMongoConverter()} and
|
||||
|
||||
@@ -50,6 +50,7 @@ import org.springframework.core.type.filter.AssignableTypeFilter;
|
||||
import org.springframework.core.type.filter.TypeFilter;
|
||||
import org.springframework.data.annotation.Persistent;
|
||||
import org.springframework.data.config.BeanComponentDefinitionBuilder;
|
||||
import org.springframework.data.mapping.context.MappingContextIsNewStrategyFactory;
|
||||
import org.springframework.data.mongodb.core.convert.CustomConversions;
|
||||
import org.springframework.data.mongodb.core.convert.MappingMongoConverter;
|
||||
import org.springframework.data.mongodb.core.index.MongoPersistentEntityIndexCreator;
|
||||
@@ -90,6 +91,8 @@ public class MappingMongoConverterParser implements BeanDefinitionParser {
|
||||
BeanDefinition conversionsDefinition = getCustomConversions(element, parserContext);
|
||||
String ctxRef = potentiallyCreateMappingContext(element, parserContext, conversionsDefinition, id);
|
||||
|
||||
createIsNewStrategyFactoryBeanDefinition(ctxRef, parserContext, element);
|
||||
|
||||
// Need a reference to a Mongo instance
|
||||
String dbFactoryRef = element.getAttribute("db-factory-ref");
|
||||
if (!StringUtils.hasText(dbFactoryRef)) {
|
||||
@@ -115,6 +118,7 @@ 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));
|
||||
@@ -245,7 +249,7 @@ public class MappingMongoConverterParser implements BeanDefinitionParser {
|
||||
return null;
|
||||
}
|
||||
|
||||
public static Set<String> getInititalEntityClasses(Element element, BeanDefinitionBuilder builder) {
|
||||
private static Set<String> getInititalEntityClasses(Element element, BeanDefinitionBuilder builder) {
|
||||
|
||||
String basePackage = element.getAttribute(BASE_PACKAGE);
|
||||
|
||||
@@ -284,6 +288,19 @@ public class MappingMongoConverterParser implements BeanDefinitionParser {
|
||||
return null;
|
||||
}
|
||||
|
||||
public static String createIsNewStrategyFactoryBeanDefinition(String mappingContextRef, ParserContext context,
|
||||
Element element) {
|
||||
|
||||
BeanDefinitionBuilder mappingContextStrategyFactoryBuilder = BeanDefinitionBuilder
|
||||
.rootBeanDefinition(MappingContextIsNewStrategyFactory.class);
|
||||
mappingContextStrategyFactoryBuilder.addConstructorArgReference(mappingContextRef);
|
||||
|
||||
BeanComponentDefinitionBuilder builder = new BeanComponentDefinitionBuilder(element, context);
|
||||
context.registerBeanComponent(builder.getComponent(mappingContextStrategyFactoryBuilder, IS_NEW_STRATEGY_FACTORY));
|
||||
|
||||
return IS_NEW_STRATEGY_FACTORY;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@link TypeFilter} that returns {@literal false} in case any of the given delegates matches.
|
||||
*
|
||||
|
||||
@@ -0,0 +1,80 @@
|
||||
/*
|
||||
* Copyright 2012 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.data.mongodb.config;
|
||||
|
||||
import org.springframework.beans.factory.config.BeanDefinition;
|
||||
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
|
||||
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
|
||||
import org.springframework.beans.factory.xml.AbstractSingleBeanDefinitionParser;
|
||||
import org.springframework.beans.factory.xml.BeanDefinitionParser;
|
||||
import org.springframework.beans.factory.xml.ParserContext;
|
||||
import org.springframework.data.config.IsNewAwareAuditingHandlerBeanDefinitionParser;
|
||||
import org.springframework.data.mongodb.core.mapping.event.AuditingEventListener;
|
||||
import org.w3c.dom.Element;
|
||||
|
||||
/**
|
||||
* {@link BeanDefinitionParser} to register a {@link AuditingEventListener} to transparently set auditing information on
|
||||
* an entity.
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
public class MongoAuditingBeanDefinitionParser extends AbstractSingleBeanDefinitionParser {
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.beans.factory.xml.AbstractSingleBeanDefinitionParser#getBeanClass(org.w3c.dom.Element)
|
||||
*/
|
||||
@Override
|
||||
protected Class<?> getBeanClass(Element element) {
|
||||
return AuditingEventListener.class;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.beans.factory.xml.AbstractBeanDefinitionParser#shouldGenerateId()
|
||||
*/
|
||||
@Override
|
||||
protected boolean shouldGenerateId() {
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.beans.factory.xml.AbstractSingleBeanDefinitionParser#doParse(org.w3c.dom.Element, org.springframework.beans.factory.xml.ParserContext, org.springframework.beans.factory.support.BeanDefinitionBuilder)
|
||||
*/
|
||||
@Override
|
||||
protected void doParse(Element element, ParserContext parserContext, BeanDefinitionBuilder builder) {
|
||||
|
||||
BeanDefinitionRegistry registry = parserContext.getRegistry();
|
||||
|
||||
if (!registry.containsBeanDefinition(BeanNames.IS_NEW_STRATEGY_FACTORY)) {
|
||||
|
||||
String mappingContextName = BeanNames.MAPPING_CONTEXT;
|
||||
|
||||
if (!registry.containsBeanDefinition(BeanNames.MAPPING_CONTEXT)) {
|
||||
mappingContextName = MappingMongoConverterParser.potentiallyCreateMappingContext(element, parserContext, null,
|
||||
BeanNames.DEFAULT_CONVERTER_BEAN_NAME);
|
||||
}
|
||||
|
||||
MappingMongoConverterParser.createIsNewStrategyFactoryBeanDefinition(mappingContextName, parserContext, element);
|
||||
}
|
||||
|
||||
BeanDefinitionParser parser = new IsNewAwareAuditingHandlerBeanDefinitionParser(BeanNames.IS_NEW_STRATEGY_FACTORY);
|
||||
BeanDefinition handlerBeanDefinition = parser.parse(element, parserContext);
|
||||
|
||||
builder.addConstructorArgValue(handlerBeanDefinition);
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2011 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.
|
||||
@@ -21,17 +21,16 @@ import org.springframework.data.repository.config.RepositoryBeanDefinitionParser
|
||||
import org.springframework.data.repository.config.RepositoryConfigurationExtension;
|
||||
|
||||
/**
|
||||
* {@link org.springframework.beans.factory.xml.NamespaceHandler} for Mongo DB based repositories.
|
||||
* {@link org.springframework.beans.factory.xml.NamespaceHandler} for Mongo DB configuration.
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
public class MongoNamespaceHandler extends NamespaceHandlerSupport {
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see org.springframework.beans.factory.xml.NamespaceHandler#init()
|
||||
*/
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.beans.factory.xml.NamespaceHandler#init()
|
||||
*/
|
||||
public void init() {
|
||||
|
||||
RepositoryConfigurationExtension extension = new MongoRepositoryConfigurationExtension();
|
||||
@@ -42,5 +41,6 @@ public class MongoNamespaceHandler extends NamespaceHandlerSupport {
|
||||
registerBeanDefinitionParser("mongo", new MongoParser());
|
||||
registerBeanDefinitionParser("db-factory", new MongoDbFactoryParser());
|
||||
registerBeanDefinitionParser("jmx", new MongoJmxParser());
|
||||
registerBeanDefinitionParser("auditing", new MongoAuditingBeanDefinitionParser());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2011 the original author or authors.
|
||||
* 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.
|
||||
@@ -31,6 +31,7 @@ import com.mongodb.ServerAddress;
|
||||
*
|
||||
* @author Mark Pollack
|
||||
* @author Oliver Gierke
|
||||
* @author Thomas Darimont
|
||||
*/
|
||||
public class ServerAddressPropertyEditor extends PropertyEditorSupport {
|
||||
|
||||
@@ -43,6 +44,11 @@ public class ServerAddressPropertyEditor extends PropertyEditorSupport {
|
||||
@Override
|
||||
public void setAsText(String replicaSetString) {
|
||||
|
||||
if (!StringUtils.hasText(replicaSetString)) {
|
||||
setValue(null);
|
||||
return;
|
||||
}
|
||||
|
||||
String[] replicaSetStringArray = StringUtils.commaDelimitedListToStringArray(replicaSetString);
|
||||
Set<ServerAddress> serverAddresses = new HashSet<ServerAddress>(replicaSetStringArray.length);
|
||||
|
||||
|
||||
@@ -112,8 +112,8 @@ public abstract class MongoDbUtils {
|
||||
String password = credentials.hasPassword() ? credentials.getPassword() : null;
|
||||
|
||||
if (!db.authenticate(username, password == null ? null : password.toCharArray())) {
|
||||
throw new CannotGetMongoDbConnectionException("Failed to authenticate to database [" + databaseName
|
||||
+ "], username = [" + username + "], password = [ -not-shown- ]", databaseName, credentials);
|
||||
throw new CannotGetMongoDbConnectionException("Failed to authenticate to database [" + databaseName + "], "
|
||||
+ credentials.toString(), databaseName, credentials);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,7 +15,9 @@
|
||||
*/
|
||||
package org.springframework.data.mongodb.core;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.beans.factory.DisposableBean;
|
||||
@@ -24,6 +26,7 @@ import org.springframework.beans.factory.InitializingBean;
|
||||
import org.springframework.dao.DataAccessException;
|
||||
import org.springframework.dao.support.PersistenceExceptionTranslator;
|
||||
import org.springframework.data.mongodb.CannotGetMongoDbConnectionException;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
import com.mongodb.Mongo;
|
||||
import com.mongodb.MongoOptions;
|
||||
@@ -36,6 +39,7 @@ import com.mongodb.WriteConcern;
|
||||
* @author Thomas Risberg
|
||||
* @author Graeme Rocher
|
||||
* @author Oliver Gierke
|
||||
* @author Thomas Darimont
|
||||
* @since 1.0
|
||||
*/
|
||||
public class MongoFactoryBean implements FactoryBean<Mongo>, InitializingBean, DisposableBean,
|
||||
@@ -57,11 +61,38 @@ public class MongoFactoryBean implements FactoryBean<Mongo>, InitializingBean, D
|
||||
}
|
||||
|
||||
public void setReplicaSetSeeds(ServerAddress[] replicaSetSeeds) {
|
||||
this.replicaSetSeeds = Arrays.asList(replicaSetSeeds);
|
||||
this.replicaSetSeeds = filterNonNullElementsAsList(replicaSetSeeds);
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated use {@link #setReplicaSetSeeds(ServerAddress[])} instead
|
||||
*
|
||||
* @param replicaPair
|
||||
*/
|
||||
@Deprecated
|
||||
public void setReplicaPair(ServerAddress[] replicaPair) {
|
||||
this.replicaPair = Arrays.asList(replicaPair);
|
||||
this.replicaPair = filterNonNullElementsAsList(replicaPair);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param elements the elements to filter <T>
|
||||
* @return a new unmodifiable {@link List#} from the given elements without nulls
|
||||
*/
|
||||
private <T> List<T> filterNonNullElementsAsList(T[] elements) {
|
||||
|
||||
if (elements == null) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
List<T> candidateElements = new ArrayList<T>();
|
||||
|
||||
for (T element : elements) {
|
||||
if (element != null) {
|
||||
candidateElements.add(element);
|
||||
}
|
||||
}
|
||||
|
||||
return Collections.unmodifiableList(candidateElements);
|
||||
}
|
||||
|
||||
public void setHost(String host) {
|
||||
@@ -126,15 +157,15 @@ public class MongoFactoryBean implements FactoryBean<Mongo>, InitializingBean, D
|
||||
mongoOptions = new MongoOptions();
|
||||
}
|
||||
|
||||
if (replicaPair != null) {
|
||||
if (!isNullOrEmpty(replicaPair)) {
|
||||
if (replicaPair.size() < 2) {
|
||||
throw new CannotGetMongoDbConnectionException("A replica pair must have two server entries");
|
||||
}
|
||||
mongo = new Mongo(replicaPair.get(0), replicaPair.get(1), mongoOptions);
|
||||
} else if (replicaSetSeeds != null) {
|
||||
} else if (!isNullOrEmpty(replicaSetSeeds)) {
|
||||
mongo = new Mongo(replicaSetSeeds, mongoOptions);
|
||||
} else {
|
||||
String mongoHost = host != null ? host : defaultOptions.getHost();
|
||||
String mongoHost = StringUtils.hasText(host) ? host : defaultOptions.getHost();
|
||||
mongo = port != null ? new Mongo(new ServerAddress(mongoHost, port), mongoOptions) : new Mongo(mongoHost,
|
||||
mongoOptions);
|
||||
}
|
||||
@@ -146,6 +177,10 @@ public class MongoFactoryBean implements FactoryBean<Mongo>, InitializingBean, D
|
||||
this.mongo = mongo;
|
||||
}
|
||||
|
||||
private boolean isNullOrEmpty(Collection<?> elements) {
|
||||
return elements == null || elements.isEmpty();
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.beans.factory.DisposableBean#destroy()
|
||||
|
||||
@@ -247,7 +247,7 @@ public interface MongoOperations {
|
||||
* Query for a list of objects of type T from the collection used by the entity class.
|
||||
* <p/>
|
||||
* The object is converted from the MongoDB native representation using an instance of {@see MongoConverter}. Unless
|
||||
* configured otherwise, an instance of SimpleMongoConverter will be used.
|
||||
* configured otherwise, an instance of MappingMongoConverter will be used.
|
||||
* <p/>
|
||||
* If your collection does not contain a homogeneous collection of types, this operation will not be an efficient way
|
||||
* to map objects since the test for class type is done in the client and not on the server.
|
||||
@@ -261,7 +261,7 @@ public interface MongoOperations {
|
||||
* Query for a list of objects of type T from the specified collection.
|
||||
* <p/>
|
||||
* The object is converted from the MongoDB native representation using an instance of {@see MongoConverter}. Unless
|
||||
* configured otherwise, an instance of SimpleMongoConverter will be used.
|
||||
* configured otherwise, an instance of MappingMongoConverter will be used.
|
||||
* <p/>
|
||||
* If your collection does not contain a homogeneous collection of types, this operation will not be an efficient way
|
||||
* to map objects since the test for class type is done in the client and not on the server.
|
||||
@@ -382,7 +382,7 @@ public interface MongoOperations {
|
||||
* specified type.
|
||||
* <p/>
|
||||
* The object is converted from the MongoDB native representation using an instance of {@see MongoConverter}. Unless
|
||||
* configured otherwise, an instance of SimpleMongoConverter will be used.
|
||||
* configured otherwise, an instance of MappingMongoConverter will be used.
|
||||
* <p/>
|
||||
* The query is specified as a {@link Query} which can be created either using the {@link BasicQuery} or the more
|
||||
* feature rich {@link Query}.
|
||||
@@ -399,7 +399,7 @@ public interface MongoOperations {
|
||||
* type.
|
||||
* <p/>
|
||||
* The object is converted from the MongoDB native representation using an instance of {@see MongoConverter}. Unless
|
||||
* configured otherwise, an instance of SimpleMongoConverter will be used.
|
||||
* configured otherwise, an instance of MappingMongoConverter will be used.
|
||||
* <p/>
|
||||
* The query is specified as a {@link Query} which can be created either using the {@link BasicQuery} or the more
|
||||
* feature rich {@link Query}.
|
||||
@@ -417,7 +417,7 @@ public interface MongoOperations {
|
||||
* Map the results of an ad-hoc query on the collection for the entity class to a List of the specified type.
|
||||
* <p/>
|
||||
* The object is converted from the MongoDB native representation using an instance of {@see MongoConverter}. Unless
|
||||
* configured otherwise, an instance of SimpleMongoConverter will be used.
|
||||
* configured otherwise, an instance of MappingMongoConverter will be used.
|
||||
* <p/>
|
||||
* The query is specified as a {@link Query} which can be created either using the {@link BasicQuery} or the more
|
||||
* feature rich {@link Query}.
|
||||
@@ -433,7 +433,7 @@ public interface MongoOperations {
|
||||
* Map the results of an ad-hoc query on the specified collection to a List of the specified type.
|
||||
* <p/>
|
||||
* The object is converted from the MongoDB native representation using an instance of {@see MongoConverter}. Unless
|
||||
* configured otherwise, an instance of SimpleMongoConverter will be used.
|
||||
* configured otherwise, an instance of MappingMongoConverter will be used.
|
||||
* <p/>
|
||||
* The query is specified as a {@link Query} which can be created either using the {@link BasicQuery} or the more
|
||||
* feature rich {@link Query}.
|
||||
@@ -501,7 +501,7 @@ public interface MongoOperations {
|
||||
* type. The first document that matches the query is returned and also removed from the collection in the database.
|
||||
* <p/>
|
||||
* The object is converted from the MongoDB native representation using an instance of {@see MongoConverter}. Unless
|
||||
* configured otherwise, an instance of SimpleMongoConverter will be used.
|
||||
* configured otherwise, an instance of MappingMongoConverter will be used.
|
||||
* <p/>
|
||||
* The query is specified as a {@link Query} which can be created either using the {@link BasicQuery} or the more
|
||||
* feature rich {@link Query}.
|
||||
@@ -555,7 +555,7 @@ public interface MongoOperations {
|
||||
* Insert the object into the specified collection.
|
||||
* <p/>
|
||||
* The object is converted to the MongoDB native representation using an instance of {@see MongoConverter}. Unless
|
||||
* configured otherwise, an instance of SimpleMongoConverter will be used.
|
||||
* configured otherwise, an instance of MappingMongoConverter will be used.
|
||||
* <p/>
|
||||
* Insert is used to initially store the object into the database. To update an existing object use the save method.
|
||||
*
|
||||
@@ -593,7 +593,7 @@ public interface MongoOperations {
|
||||
* object is not already present, that is an 'upsert'.
|
||||
* <p/>
|
||||
* The object is converted to the MongoDB native representation using an instance of {@see MongoConverter}. Unless
|
||||
* configured otherwise, an instance of SimpleMongoConverter will be used.
|
||||
* configured otherwise, an instance of MappingMongoConverter will be used.
|
||||
* <p/>
|
||||
* If you object has an "Id' property, it will be set with the generated Id from MongoDB. If your Id property is a
|
||||
* String then MongoDB ObjectId will be used to populate that string. Otherwise, the conversion from ObjectId to your
|
||||
@@ -610,7 +610,7 @@ public interface MongoOperations {
|
||||
* is an 'upsert'.
|
||||
* <p/>
|
||||
* The object is converted to the MongoDB native representation using an instance of {@see MongoConverter}. Unless
|
||||
* configured otherwise, an instance of SimpleMongoConverter will be used.
|
||||
* configured otherwise, an instance of MappingMongoConverter will be used.
|
||||
* <p/>
|
||||
* If you object has an "Id' property, it will be set with the generated Id from MongoDB. If your Id property is a
|
||||
* String then MongoDB ObjectId will be used to populate that string. Otherwise, the conversion from ObjectId to your
|
||||
@@ -734,4 +734,4 @@ public interface MongoOperations {
|
||||
* @return
|
||||
*/
|
||||
MongoConverter getConverter();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2010-2012 the original author or authors.
|
||||
* Copyright 2010-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.
|
||||
@@ -44,7 +44,6 @@ import org.springframework.core.convert.ConversionService;
|
||||
import org.springframework.core.io.Resource;
|
||||
import org.springframework.core.io.ResourceLoader;
|
||||
import org.springframework.dao.DataAccessException;
|
||||
import org.springframework.dao.DataIntegrityViolationException;
|
||||
import org.springframework.dao.InvalidDataAccessApiUsageException;
|
||||
import org.springframework.dao.OptimisticLockingFailureException;
|
||||
import org.springframework.data.authentication.UserCredentials;
|
||||
@@ -53,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;
|
||||
@@ -666,8 +666,9 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware {
|
||||
|
||||
MongoPersistentEntity<?> mongoPersistentEntity = getPersistentEntity(entity.getClass());
|
||||
|
||||
if (mongoPersistentEntity == null || mongoPersistentEntity.hasVersionProperty()) {
|
||||
BeanWrapper<PersistentEntity<Object, ?>, Object> wrapper = BeanWrapper.create(entity, null);
|
||||
if (mongoPersistentEntity != null && mongoPersistentEntity.hasVersionProperty()) {
|
||||
BeanWrapper<PersistentEntity<Object, ?>, Object> wrapper = BeanWrapper.create(entity,
|
||||
this.mongoConverter.getConversionService());
|
||||
wrapper.setProperty(mongoPersistentEntity.getVersionProperty(), 0);
|
||||
}
|
||||
}
|
||||
@@ -770,8 +771,7 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware {
|
||||
|
||||
// Fresh instance -> initialize version property
|
||||
if (version == null) {
|
||||
beanWrapper.setProperty(versionProperty, 0);
|
||||
doSave(collectionName, objectToSave, this.mongoConverter);
|
||||
doInsert(collectionName, objectToSave, this.mongoConverter);
|
||||
} else {
|
||||
|
||||
assertUpdateableIdIfNotSet(objectToSave);
|
||||
@@ -792,12 +792,11 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware {
|
||||
maybeEmitEvent(new BeforeSaveEvent<T>(objectToSave, dbObject));
|
||||
Update update = Update.fromDBObject(dbObject, ID_FIELD);
|
||||
|
||||
updateFirst(query, update, objectToSave.getClass());
|
||||
doUpdate(collectionName, query, update, objectToSave.getClass(), false, false);
|
||||
maybeEmitEvent(new AfterSaveEvent<T>(objectToSave, dbObject));
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
protected <T> void doSave(String collectionName, T objectToSave, MongoWriter<T> writer) {
|
||||
|
||||
assertUpdateableIdIfNotSet(objectToSave);
|
||||
@@ -810,7 +809,7 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware {
|
||||
writer.write(objectToSave, dbDoc);
|
||||
} else {
|
||||
try {
|
||||
objectToSave = (T) JSON.parse((String) objectToSave);
|
||||
dbDoc = (DBObject) JSON.parse((String) objectToSave);
|
||||
} catch (JSONParseException e) {
|
||||
throw new MappingException("Could not parse given String to save into a JSON document!", e);
|
||||
}
|
||||
@@ -941,7 +940,7 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware {
|
||||
if (entity != null && entity.hasVersionProperty() && !multi) {
|
||||
if (writeResult.getN() == 0) {
|
||||
throw new OptimisticLockingFailureException("Optimistic lock exception on saving entity: "
|
||||
+ updateObj.toMap().toString());
|
||||
+ updateObj.toMap().toString() + " to collection " + collectionName);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -981,11 +980,12 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware {
|
||||
|
||||
Assert.notNull(object);
|
||||
|
||||
MongoPersistentEntity<?> entity = mappingContext.getPersistentEntity(object.getClass());
|
||||
Class<?> objectType = object.getClass();
|
||||
MongoPersistentEntity<?> entity = mappingContext.getPersistentEntity(objectType);
|
||||
MongoPersistentProperty idProp = entity == null ? null : entity.getIdProperty();
|
||||
|
||||
if (idProp == null) {
|
||||
throw new MappingException("No id property found for object of type " + entity.getType().getName());
|
||||
throw new MappingException("No id property found for object of type " + objectType);
|
||||
}
|
||||
|
||||
ConversionService service = mongoConverter.getConversionService();
|
||||
@@ -1306,8 +1306,8 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware {
|
||||
/**
|
||||
* Map the results of an ad-hoc query on the default MongoDB collection to a List of the specified type. The object is
|
||||
* converted from the MongoDB native representation using an instance of {@see MongoConverter}. Unless configured
|
||||
* otherwise, an instance of SimpleMongoConverter will be used. The query document is specified as a standard DBObject
|
||||
* and so is the fields specification. Can be overridden by subclasses.
|
||||
* otherwise, an instance of MappingMongoConverter will be used. The query document is specified as a standard
|
||||
* DBObject and so is the fields specification. Can be overridden by subclasses.
|
||||
*
|
||||
* @param collectionName name of the collection to retrieve the objects from
|
||||
* @param query the query document that specifies the criteria used to find a record
|
||||
@@ -1408,19 +1408,15 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware {
|
||||
|
||||
MongoPersistentEntity<?> entity = mappingContext.getPersistentEntity(entityClass);
|
||||
|
||||
DBObject updateObj = update.getUpdateObject();
|
||||
for (String key : updateObj.keySet()) {
|
||||
updateObj.put(key, mongoConverter.convertToMongoType(updateObj.get(key)));
|
||||
}
|
||||
|
||||
DBObject mappedUpdate = mapper.getMappedObject(update.getUpdateObject(), entity);
|
||||
DBObject mappedQuery = mapper.getMappedObject(query, entity);
|
||||
|
||||
if (LOGGER.isDebugEnabled()) {
|
||||
LOGGER.debug("findAndModify using query: " + mappedQuery + " fields: " + fields + " sort: " + sort
|
||||
+ " for class: " + entityClass + " and update: " + updateObj + " in collection: " + collectionName);
|
||||
+ " for class: " + entityClass + " and update: " + mappedUpdate + " in collection: " + collectionName);
|
||||
}
|
||||
|
||||
return executeFindOneInternal(new FindAndModifyCallback(mappedQuery, fields, sort, updateObj, options),
|
||||
return executeFindOneInternal(new FindAndModifyCallback(mappedQuery, fields, sort, mappedUpdate, options),
|
||||
new ReadDbObjectCallback<T>(readerToUse, entityClass), collectionName);
|
||||
}
|
||||
|
||||
@@ -1647,7 +1643,7 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware {
|
||||
}
|
||||
|
||||
if (writeResultChecking == WriteResultChecking.EXCEPTION) {
|
||||
throw new DataIntegrityViolationException(message);
|
||||
throw new MongoDataIntegrityViolationException(message, writeResult, operation);
|
||||
} else {
|
||||
LOGGER.error(message);
|
||||
return;
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
/*
|
||||
* Copyright (c) 2011 by the original author(s).
|
||||
* 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
|
||||
* 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,
|
||||
@@ -17,9 +17,11 @@ 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;
|
||||
@@ -31,6 +33,7 @@ import org.springframework.core.convert.converter.ConverterFactory;
|
||||
import org.springframework.core.convert.converter.GenericConverter;
|
||||
import org.springframework.core.convert.converter.GenericConverter.ConvertiblePair;
|
||||
import org.springframework.core.convert.support.GenericConversionService;
|
||||
import org.springframework.data.convert.JodaTimeConverters;
|
||||
import org.springframework.data.convert.ReadingConverter;
|
||||
import org.springframework.data.convert.WritingConverter;
|
||||
import org.springframework.data.mapping.model.SimpleTypeHolder;
|
||||
@@ -62,6 +65,7 @@ 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;
|
||||
|
||||
@@ -84,6 +88,7 @@ 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);
|
||||
@@ -93,6 +98,7 @@ public class CustomConversions {
|
||||
this.converters.add(StringToBigIntegerConverter.INSTANCE);
|
||||
this.converters.add(URLToStringConverter.INSTANCE);
|
||||
this.converters.add(StringToURLConverter.INSTANCE);
|
||||
this.converters.addAll(JodaTimeConverters.getConvertersToRegister());
|
||||
this.converters.addAll(converters);
|
||||
|
||||
for (Object c : this.converters) {
|
||||
@@ -266,9 +272,11 @@ public class CustomConversions {
|
||||
* @return
|
||||
*/
|
||||
public boolean hasCustomReadTarget(Class<?> source, Class<?> expectedTargetType) {
|
||||
|
||||
Assert.notNull(source);
|
||||
Assert.notNull(expectedTargetType);
|
||||
return getCustomTarget(source, expectedTargetType, readingPairs) != null;
|
||||
|
||||
return getCustomReadTarget(source, expectedTargetType) != null;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -297,8 +305,32 @@ 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() {
|
||||
@@ -311,4 +343,30 @@ 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -31,11 +31,13 @@ import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.ApplicationContextAware;
|
||||
import org.springframework.core.CollectionFactory;
|
||||
import org.springframework.core.convert.ConversionException;
|
||||
import org.springframework.core.convert.ConversionService;
|
||||
import org.springframework.core.convert.support.ConversionServiceFactory;
|
||||
import org.springframework.data.convert.EntityInstantiator;
|
||||
import org.springframework.data.convert.TypeMapper;
|
||||
import org.springframework.data.mapping.Association;
|
||||
import org.springframework.data.mapping.AssociationHandler;
|
||||
import org.springframework.data.mapping.PreferredConstructor.Parameter;
|
||||
import org.springframework.data.mapping.PropertyHandler;
|
||||
import org.springframework.data.mapping.context.MappingContext;
|
||||
import org.springframework.data.mapping.model.BeanWrapper;
|
||||
@@ -46,6 +48,7 @@ import org.springframework.data.mapping.model.PersistentEntityParameterValueProv
|
||||
import org.springframework.data.mapping.model.PropertyValueProvider;
|
||||
import org.springframework.data.mapping.model.SpELContext;
|
||||
import org.springframework.data.mapping.model.SpELExpressionEvaluator;
|
||||
import org.springframework.data.mapping.model.SpELExpressionParameterValueProvider;
|
||||
import org.springframework.data.mongodb.MongoDbFactory;
|
||||
import org.springframework.data.mongodb.core.mapping.MongoPersistentEntity;
|
||||
import org.springframework.data.mongodb.core.mapping.MongoPersistentProperty;
|
||||
@@ -215,9 +218,9 @@ public class MappingMongoConverter extends AbstractMongoConverter implements App
|
||||
MongoDbPropertyValueProvider provider = new MongoDbPropertyValueProvider(source, evaluator, parent);
|
||||
PersistentEntityParameterValueProvider<MongoPersistentProperty> parameterProvider = new PersistentEntityParameterValueProvider<MongoPersistentProperty>(
|
||||
entity, provider, parent);
|
||||
parameterProvider.setSpELEvaluator(evaluator);
|
||||
|
||||
return parameterProvider;
|
||||
return new ConverterAwareSpELExpressionParameterValueProvider(evaluator, conversionService, parameterProvider,
|
||||
parent);
|
||||
}
|
||||
|
||||
private <S extends Object> S read(final MongoPersistentEntity<S> entity, final DBObject dbo, Object parent) {
|
||||
@@ -235,10 +238,7 @@ public class MappingMongoConverter extends AbstractMongoConverter implements App
|
||||
entity.doWithProperties(new PropertyHandler<MongoPersistentProperty>() {
|
||||
public void doWithPersistentProperty(MongoPersistentProperty prop) {
|
||||
|
||||
boolean isConstructorProperty = entity.isConstructorArgument(prop);
|
||||
boolean hasValueForProperty = dbo.containsField(prop.getFieldName());
|
||||
|
||||
if (!hasValueForProperty || isConstructorProperty) {
|
||||
if (!dbo.containsField(prop.getFieldName()) || entity.isConstructorArgument(prop)) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -829,7 +829,7 @@ public class MappingMongoConverter extends AbstractMongoConverter implements App
|
||||
return conversionService.convert(obj, target);
|
||||
}
|
||||
|
||||
if (null != obj && conversions.isSimpleType(obj.getClass())) {
|
||||
if (conversions.isSimpleType(obj.getClass())) {
|
||||
// Doesn't need conversion
|
||||
return getPotentiallyConvertedSimpleWrite(obj);
|
||||
}
|
||||
@@ -942,7 +942,6 @@ public class MappingMongoConverter extends AbstractMongoConverter implements App
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.convert.PropertyValueProvider#getPropertyValue(org.springframework.data.mapping.PersistentProperty)
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public <T> T getPropertyValue(MongoPersistentProperty property) {
|
||||
|
||||
String expression = property.getSpelExpression();
|
||||
@@ -952,20 +951,60 @@ public class MappingMongoConverter extends AbstractMongoConverter implements App
|
||||
return null;
|
||||
}
|
||||
|
||||
TypeInformation<?> type = property.getTypeInformation();
|
||||
Class<?> rawType = type.getType();
|
||||
return readValue(value, property.getTypeInformation(), parent);
|
||||
}
|
||||
}
|
||||
|
||||
if (conversions.hasCustomReadTarget(value.getClass(), rawType)) {
|
||||
return (T) conversionService.convert(value, rawType);
|
||||
} else if (value instanceof DBRef) {
|
||||
return (T) (rawType.equals(DBRef.class) ? value : read(type, ((DBRef) value).fetch(), parent));
|
||||
} else if (value instanceof BasicDBList) {
|
||||
return (T) readCollectionOrArray(type, (BasicDBList) value, parent);
|
||||
} else if (value instanceof DBObject) {
|
||||
return (T) read(type, (DBObject) value, parent);
|
||||
} else {
|
||||
return (T) getPotentiallyConvertedSimpleRead(value, rawType);
|
||||
}
|
||||
/**
|
||||
* Extension of {@link SpELExpressionParameterValueProvider} to recursively trigger value conversion on the raw
|
||||
* resolved SpEL value.
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
private class ConverterAwareSpELExpressionParameterValueProvider extends
|
||||
SpELExpressionParameterValueProvider<MongoPersistentProperty> {
|
||||
|
||||
private final Object parent;
|
||||
|
||||
/**
|
||||
* Creates a new {@link ConverterAwareSpELExpressionParameterValueProvider}.
|
||||
*
|
||||
* @param evaluator must not be {@literal null}.
|
||||
* @param conversionService must not be {@literal null}.
|
||||
* @param delegate must not be {@literal null}.
|
||||
*/
|
||||
public ConverterAwareSpELExpressionParameterValueProvider(SpELExpressionEvaluator evaluator,
|
||||
ConversionService conversionService, ParameterValueProvider<MongoPersistentProperty> delegate, Object parent) {
|
||||
|
||||
super(evaluator, conversionService, delegate);
|
||||
this.parent = parent;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.mapping.model.SpELExpressionParameterValueProvider#potentiallyConvertSpelValue(java.lang.Object, org.springframework.data.mapping.PreferredConstructor.Parameter)
|
||||
*/
|
||||
@Override
|
||||
protected <T> T potentiallyConvertSpelValue(Object object, Parameter<T, MongoPersistentProperty> parameter) {
|
||||
return readValue(object, parameter.getType(), parent);
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private <T> T readValue(Object value, TypeInformation<?> type, Object parent) {
|
||||
|
||||
Class<?> rawType = type.getType();
|
||||
|
||||
if (conversions.hasCustomReadTarget(value.getClass(), rawType)) {
|
||||
return (T) conversionService.convert(value, rawType);
|
||||
} else if (value instanceof DBRef) {
|
||||
return (T) (rawType.equals(DBRef.class) ? value : read(type, ((DBRef) value).fetch(), parent));
|
||||
} else if (value instanceof BasicDBList) {
|
||||
return (T) readCollectionOrArray(type, (BasicDBList) value, parent);
|
||||
} else if (value instanceof DBObject) {
|
||||
return (T) read(type, (DBObject) value, parent);
|
||||
} else {
|
||||
return (T) getPotentiallyConvertedSimpleRead(value, rawType);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2011-2012 the original author or authors.
|
||||
* 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.
|
||||
@@ -18,6 +18,7 @@ package org.springframework.data.mongodb.core.convert;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import org.bson.types.ObjectId;
|
||||
import org.springframework.core.convert.ConversionException;
|
||||
@@ -41,6 +42,7 @@ import com.mongodb.DBRef;
|
||||
*
|
||||
* @author Jon Brisbin
|
||||
* @author Oliver Gierke
|
||||
* @author Patryk Wasik
|
||||
*/
|
||||
public class QueryMapper {
|
||||
|
||||
@@ -83,11 +85,22 @@ public class QueryMapper {
|
||||
|
||||
for (String key : query.keySet()) {
|
||||
|
||||
MongoPersistentProperty targetProperty = getTargetProperty(key, entity);
|
||||
String newKey = determineKey(key, entity);
|
||||
Object value = query.get(key);
|
||||
if (Keyword.isKeyword(key)) {
|
||||
result.putAll(getMappedKeyword(new Keyword(query, key), entity));
|
||||
continue;
|
||||
}
|
||||
|
||||
result.put(newKey, getMappedValue(value, targetProperty, newKey));
|
||||
Field field = entity == null ? new Field(key) : new MetadataBackedField(key, entity, mappingContext);
|
||||
|
||||
Object rawValue = query.get(key);
|
||||
String newKey = field.getMappedKey();
|
||||
|
||||
if (Keyword.isKeyword(rawValue) && !field.isIdField()) {
|
||||
Keyword keyword = new Keyword((DBObject) rawValue);
|
||||
result.put(newKey, getMappedKeyword(field, keyword));
|
||||
} else {
|
||||
result.put(newKey, getMappedValue(field, query.get(key)));
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
@@ -103,13 +116,14 @@ public class QueryMapper {
|
||||
private DBObject getMappedKeyword(Keyword query, MongoPersistentEntity<?> entity) {
|
||||
|
||||
// $or/$nor
|
||||
if (query.key.matches(N_OR_PATTERN)) {
|
||||
if (query.key.matches(N_OR_PATTERN) || query.value instanceof Iterable) {
|
||||
|
||||
Iterable<?> conditions = (Iterable<?>) query.value;
|
||||
BasicDBList newConditions = new BasicDBList();
|
||||
|
||||
for (Object condition : conditions) {
|
||||
newConditions.add(getMappedObject((DBObject) condition, entity));
|
||||
newConditions.add(condition instanceof DBObject ? getMappedObject((DBObject) condition, entity)
|
||||
: convertSimpleOrDBObject(condition, entity));
|
||||
}
|
||||
|
||||
return new BasicDBObject(query.key, newConditions);
|
||||
@@ -121,38 +135,34 @@ public class QueryMapper {
|
||||
/**
|
||||
* Returns the mapped keyword considered defining a criteria for the given property.
|
||||
*
|
||||
* @param keyword
|
||||
* @param property
|
||||
* @param keyword
|
||||
* @return
|
||||
*/
|
||||
public DBObject getMappedKeyword(Keyword keyword, MongoPersistentProperty property) {
|
||||
private DBObject getMappedKeyword(Field property, Keyword keyword) {
|
||||
|
||||
if (property.isAssociation()) {
|
||||
convertAssociation(keyword.value, property);
|
||||
}
|
||||
boolean needsAssociationConversion = property.isAssociation() && !keyword.isExists();
|
||||
Object value = needsAssociationConversion ? convertAssociation(keyword.value, property.getProperty())
|
||||
: getMappedValue(property.with(keyword.key), keyword.value);
|
||||
|
||||
return new BasicDBObject(keyword.key, getMappedValue(keyword.value, property, keyword.key));
|
||||
return new BasicDBObject(keyword.key, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the mapped value for the given source object assuming it's a value for the given
|
||||
* {@link MongoPersistentProperty}.
|
||||
*
|
||||
* @param source the source object to be mapped
|
||||
* @param value the source object to be mapped
|
||||
* @param property the property the value is a value for
|
||||
* @param newKey the key the value will be bound to eventually
|
||||
* @return
|
||||
*/
|
||||
private Object getMappedValue(Object source, MongoPersistentProperty property, String newKey) {
|
||||
private Object getMappedValue(Field documentField, Object value) {
|
||||
|
||||
if (property == null) {
|
||||
return convertSimpleOrDBObject(source, null);
|
||||
}
|
||||
if (documentField.isIdField()) {
|
||||
|
||||
if (property.isIdProperty() || "_id".equals(newKey)) {
|
||||
|
||||
if (source instanceof DBObject) {
|
||||
DBObject valueDbo = (DBObject) source;
|
||||
if (value instanceof DBObject) {
|
||||
DBObject valueDbo = (DBObject) value;
|
||||
if (valueDbo.containsField("$in") || valueDbo.containsField("$nin")) {
|
||||
String inKey = valueDbo.containsField("$in") ? "$in" : "$nin";
|
||||
List<Object> ids = new ArrayList<Object>();
|
||||
@@ -163,63 +173,25 @@ public class QueryMapper {
|
||||
} else if (valueDbo.containsField("$ne")) {
|
||||
valueDbo.put("$ne", convertId(valueDbo.get("$ne")));
|
||||
} else {
|
||||
return getMappedObject((DBObject) source, null);
|
||||
return getMappedObject((DBObject) value, null);
|
||||
}
|
||||
|
||||
return valueDbo;
|
||||
|
||||
} else {
|
||||
return convertId(source);
|
||||
return convertId(value);
|
||||
}
|
||||
}
|
||||
|
||||
if (property.isAssociation()) {
|
||||
return Keyword.isKeyword(source) ? getMappedKeyword(new Keyword(source), property) : convertAssociation(source,
|
||||
property);
|
||||
if (Keyword.isKeyword(value)) {
|
||||
return getMappedKeyword(new Keyword((DBObject) value), null);
|
||||
}
|
||||
|
||||
return convertSimpleOrDBObject(source, mappingContext.getPersistentEntity(property));
|
||||
}
|
||||
|
||||
private MongoPersistentProperty getTargetProperty(String key, MongoPersistentEntity<?> entity) {
|
||||
|
||||
if (isIdKey(key, entity)) {
|
||||
return entity.getIdProperty();
|
||||
if (documentField.isAssociation()) {
|
||||
return convertAssociation(value, documentField.getProperty());
|
||||
}
|
||||
|
||||
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 && DEFAULT_ID_NAMES.contains(key)) {
|
||||
return "_id";
|
||||
}
|
||||
|
||||
PersistentPropertyPath<MongoPersistentProperty> path = getPath(key, entity);
|
||||
return path == null ? key : path.toDotPath(MongoPersistentProperty.PropertyToFieldNameConverter.INSTANCE);
|
||||
return convertSimpleOrDBObject(value, documentField.getPropertyEntity());
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -243,7 +215,7 @@ public class QueryMapper {
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts the given source assuming it's actually an association to anoter object.
|
||||
* Converts the given source assuming it's actually an association to another object.
|
||||
*
|
||||
* @param source
|
||||
* @param property
|
||||
@@ -263,31 +235,19 @@ 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;
|
||||
}
|
||||
|
||||
MongoPersistentProperty idProperty = entity.getIdProperty();
|
||||
|
||||
if (idProperty != null) {
|
||||
return idProperty.getName().equals(key) || idProperty.getFieldName().equals(key);
|
||||
}
|
||||
|
||||
return DEFAULT_ID_NAMES.contains(key);
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts the given raw id value into either {@link ObjectId} or {@link String}.
|
||||
*
|
||||
@@ -315,16 +275,27 @@ public class QueryMapper {
|
||||
String key;
|
||||
Object value;
|
||||
|
||||
Keyword(Object source) {
|
||||
public Keyword(DBObject source, String key) {
|
||||
this.key = key;
|
||||
this.value = source.get(key);
|
||||
}
|
||||
|
||||
Assert.isInstanceOf(DBObject.class, source);
|
||||
public Keyword(DBObject dbObject) {
|
||||
|
||||
DBObject value = (DBObject) source;
|
||||
Set<String> keys = dbObject.keySet();
|
||||
Assert.isTrue(keys.size() == 1, "Can only use a single value DBObject!");
|
||||
|
||||
Assert.isTrue(value.keySet().size() == 1, "Keyword must have a single key only!");
|
||||
this.key = keys.iterator().next();
|
||||
this.value = dbObject.get(key);
|
||||
}
|
||||
|
||||
this.key = value.keySet().iterator().next();
|
||||
this.value = value.get(key);
|
||||
/**
|
||||
* Returns whether the current keyword is the {@code $exists} keyword.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public boolean isExists() {
|
||||
return "$exists".equalsIgnoreCase(key);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -334,7 +305,11 @@ public class QueryMapper {
|
||||
* @param value
|
||||
* @return
|
||||
*/
|
||||
static boolean isKeyword(Object value) {
|
||||
public static boolean isKeyword(Object value) {
|
||||
|
||||
if (value instanceof String) {
|
||||
return ((String) value).startsWith("$");
|
||||
}
|
||||
|
||||
if (!(value instanceof DBObject)) {
|
||||
return false;
|
||||
@@ -344,4 +319,192 @@ 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
/**
|
||||
* Spring Data MongoDB specific converter infrastructure.
|
||||
*/
|
||||
package org.springframework.data.mongodb.core.convert;
|
||||
|
||||
@@ -0,0 +1,43 @@
|
||||
/*
|
||||
* 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.geo;
|
||||
|
||||
/**
|
||||
* Value object to create custom {@link Metric}s on the fly.
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
public class CustomMetric implements Metric {
|
||||
|
||||
private final double multiplier;
|
||||
|
||||
/**
|
||||
* Creates a custom {@link Metric} using the given multiplier.
|
||||
*
|
||||
* @param multiplier
|
||||
*/
|
||||
public CustomMetric(double multiplier) {
|
||||
this.multiplier = multiplier;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.mongodb.core.geo.Metric#getMultiplier()
|
||||
*/
|
||||
public double getMultiplier() {
|
||||
return multiplier;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
/**
|
||||
* Support for MongoDB geo-spatial queries.
|
||||
*/
|
||||
package org.springframework.data.mongodb.core.geo;
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
/**
|
||||
* Support for MongoDB document indexing.
|
||||
*/
|
||||
package org.springframework.data.mongodb.core.index;
|
||||
|
||||
@@ -23,7 +23,6 @@ import org.springframework.context.ApplicationContextAware;
|
||||
import org.springframework.context.expression.BeanFactoryAccessor;
|
||||
import org.springframework.context.expression.BeanFactoryResolver;
|
||||
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;
|
||||
@@ -38,7 +37,6 @@ import org.springframework.util.StringUtils;
|
||||
*
|
||||
* @author Jon Brisbin
|
||||
* @author Oliver Gierke
|
||||
* @author Patryk Wasik
|
||||
*/
|
||||
public class BasicMongoPersistentEntity<T> extends BasicPersistentEntity<T, MongoPersistentProperty> implements
|
||||
MongoPersistentEntity<T>, ApplicationContextAware {
|
||||
@@ -47,8 +45,6 @@ public class BasicMongoPersistentEntity<T> extends BasicPersistentEntity<T, Mong
|
||||
private final SpelExpressionParser parser;
|
||||
private final StandardEvaluationContext context;
|
||||
|
||||
private MongoPersistentProperty versionProperty;
|
||||
|
||||
/**
|
||||
* Creates a new {@link BasicMongoPersistentEntity} with the given {@link TypeInformation}. Will default the
|
||||
* collection name to the entities simple type name.
|
||||
@@ -73,27 +69,6 @@ public class BasicMongoPersistentEntity<T> extends BasicPersistentEntity<T, Mong
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.mapping.MutablePersistentEntity#addPersistentProperty(P)
|
||||
*/
|
||||
@Override
|
||||
public void addPersistentProperty(MongoPersistentProperty property) {
|
||||
|
||||
if (property.isVersionProperty()) {
|
||||
|
||||
if (this.versionProperty != null) {
|
||||
throw new MappingException(String.format(
|
||||
"Attempt to add version property %s but already have property %s registered "
|
||||
+ "as version. Check your mapping configuration!", property.getField(), versionProperty.getField()));
|
||||
}
|
||||
|
||||
this.versionProperty = property;
|
||||
}
|
||||
|
||||
super.addPersistentProperty(property);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.context.ApplicationContextAware#setApplicationContext(org.springframework.context.ApplicationContext)
|
||||
@@ -110,27 +85,10 @@ public class BasicMongoPersistentEntity<T> extends BasicPersistentEntity<T, Mong
|
||||
* @see org.springframework.data.mongodb.core.mapping.MongoPersistentEntity#getCollection()
|
||||
*/
|
||||
public String getCollection() {
|
||||
|
||||
Expression expression = parser.parseExpression(collection, ParserContext.TEMPLATE_EXPRESSION);
|
||||
return expression.getValue(context, String.class);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.mongodb.core.mapping.MongoPersistentEntity#getVersionProperty()
|
||||
*/
|
||||
public MongoPersistentProperty getVersionProperty() {
|
||||
return versionProperty;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.mongodb.core.mapping.MongoPersistentEntity#hasVersionProperty()
|
||||
*/
|
||||
public boolean hasVersionProperty() {
|
||||
return getVersionProperty() != null;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@link Comparator} implementation inspecting the {@link MongoPersistentProperty}'s order.
|
||||
*
|
||||
|
||||
@@ -153,14 +153,6 @@ public class BasicMongoPersistentProperty extends AnnotationBasedPersistentPrope
|
||||
return getField().getAnnotation(DBRef.class);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.mongodb.core.mapping.MongoPersistentProperty#isVersionProperty()
|
||||
*/
|
||||
public boolean isVersionProperty() {
|
||||
return getField().isAnnotationPresent(Version.class);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.mongodb.core.mapping.MongoPersistentProperty#usePropertyAccess()
|
||||
|
||||
@@ -17,6 +17,7 @@ package org.springframework.data.mongodb.core.mapping;
|
||||
|
||||
import java.beans.PropertyDescriptor;
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.AbstractMap;
|
||||
|
||||
import org.springframework.beans.BeansException;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
@@ -51,7 +52,7 @@ public class MongoMappingContext extends AbstractMappingContext<BasicMongoPersis
|
||||
*/
|
||||
@Override
|
||||
protected boolean shouldCreatePersistentEntityFor(TypeInformation<?> type) {
|
||||
return !MongoSimpleTypes.HOLDER.isSimpleType(type.getType());
|
||||
return !MongoSimpleTypes.HOLDER.isSimpleType(type.getType()) && !AbstractMap.class.isAssignableFrom(type.getType());
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -21,7 +21,6 @@ import org.springframework.data.mapping.PersistentEntity;
|
||||
* MongoDB specific {@link PersistentEntity} abstraction.
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
* @author Patryk Wasik
|
||||
*/
|
||||
public interface MongoPersistentEntity<T> extends PersistentEntity<T, MongoPersistentProperty> {
|
||||
|
||||
@@ -31,19 +30,4 @@ public interface MongoPersistentEntity<T> extends PersistentEntity<T, MongoPersi
|
||||
* @return
|
||||
*/
|
||||
String getCollection();
|
||||
|
||||
/**
|
||||
* Returns the {@link MongoPersistentProperty} that represents the version attribute of an entity. Will not be
|
||||
* {@literal null} if {@link #hasVersionProperty()}.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
MongoPersistentProperty getVersionProperty();
|
||||
|
||||
/**
|
||||
* Returns whether the entity has a property representing the version of the entity.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
boolean hasVersionProperty();
|
||||
}
|
||||
|
||||
@@ -56,13 +56,6 @@ public interface MongoPersistentProperty extends PersistentProperty<MongoPersist
|
||||
*/
|
||||
DBRef getDBRef();
|
||||
|
||||
/**
|
||||
* Returns whether the property is representing the version attribute of an entity.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
boolean isVersionProperty();
|
||||
|
||||
/**
|
||||
* Simple {@link Converter} implementation to transform a {@link MongoPersistentProperty} into its field name.
|
||||
*
|
||||
|
||||
@@ -27,10 +27,13 @@ import java.lang.annotation.Target;
|
||||
*
|
||||
* @since 1.4
|
||||
* @author Patryk Wasik
|
||||
* @deprecated use {@link org.springframework.data.annotation.Version} instead.
|
||||
*/
|
||||
@Deprecated
|
||||
@Documented
|
||||
@Target({ FIELD })
|
||||
@Retention(RUNTIME)
|
||||
@org.springframework.data.annotation.Version
|
||||
public @interface Version {
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,53 @@
|
||||
/*
|
||||
* Copyright 2012 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.data.mongodb.core.mapping.event;
|
||||
|
||||
import org.springframework.context.ApplicationListener;
|
||||
import org.springframework.data.auditing.AuditingHandler;
|
||||
import org.springframework.data.auditing.IsNewAwareAuditingHandler;
|
||||
import org.springframework.data.mapping.context.MappingContext;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
* Event listener to populate auditing related fields on an entity about to be saved.
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
public class AuditingEventListener implements ApplicationListener<BeforeConvertEvent<Object>> {
|
||||
|
||||
private final IsNewAwareAuditingHandler<Object> auditingHandler;
|
||||
|
||||
/**
|
||||
* Creates a new {@link AuditingEventListener} using the given {@link MappingContext} and {@link AuditingHandler}.
|
||||
*
|
||||
* @param auditingHandler must not be {@literal null}.
|
||||
*/
|
||||
public AuditingEventListener(IsNewAwareAuditingHandler<Object> auditingHandler) {
|
||||
|
||||
Assert.notNull(auditingHandler, "IsNewAwareAuditingHandler must not be null!");
|
||||
this.auditingHandler = auditingHandler;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.context.ApplicationListener#onApplicationEvent(org.springframework.context.ApplicationEvent)
|
||||
*/
|
||||
public void onApplicationEvent(BeforeConvertEvent<Object> event) {
|
||||
|
||||
Object entity = event.getSource();
|
||||
auditingHandler.markAudited(entity);
|
||||
}
|
||||
}
|
||||
@@ -1,11 +1,11 @@
|
||||
/*
|
||||
* Copyright (c) 2011 by the original author(s).
|
||||
* 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.
|
||||
* 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,15 +13,17 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.data.mongodb.core.mapping.event;
|
||||
|
||||
/**
|
||||
* @author Jon Brisbin <jbrisbin@vmware.com>
|
||||
* Event being thrown before a domain object is converted to be persisted.
|
||||
*
|
||||
* @author Jon Brisbin
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
public class BeforeConvertEvent<T> extends MongoMappingEvent<T> {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
private static final long serialVersionUID = 252614269008845243L;
|
||||
|
||||
public BeforeConvertEvent(T source) {
|
||||
super(source, null);
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
/**
|
||||
* Mapping event callback infrastructure for the MongoDB document-to-object mapping subsystem.
|
||||
*/
|
||||
package org.springframework.data.mongodb.core.mapping.event;
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
/**
|
||||
* Infrastructure for the MongoDB document-to-object mapping subsystem.
|
||||
*/
|
||||
package org.springframework.data.mongodb.core.mapping;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2010-2011 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.
|
||||
@@ -16,30 +16,42 @@
|
||||
package org.springframework.data.mongodb.core.mapreduce;
|
||||
|
||||
/**
|
||||
* Value object to encapsulate results of a map-reduce count.
|
||||
*
|
||||
* @author Mark Pollack
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
public class MapReduceCounts {
|
||||
|
||||
private final int inputCount;
|
||||
private final int emitCount;
|
||||
private final int outputCount;
|
||||
public static MapReduceCounts NONE = new MapReduceCounts(-1, -1, -1);
|
||||
|
||||
private final long inputCount;
|
||||
private final long emitCount;
|
||||
private final long outputCount;
|
||||
|
||||
/**
|
||||
* Creates a new {@link MapReduceCounts} using the given input count, emit count, and output count.
|
||||
*
|
||||
* @param inputCount
|
||||
* @param emitCount
|
||||
* @param outputCount
|
||||
*/
|
||||
public MapReduceCounts(long inputCount, long emitCount, long outputCount) {
|
||||
|
||||
public MapReduceCounts(int inputCount, int emitCount, int outputCount) {
|
||||
super();
|
||||
this.inputCount = inputCount;
|
||||
this.emitCount = emitCount;
|
||||
this.outputCount = outputCount;
|
||||
}
|
||||
|
||||
public int getInputCount() {
|
||||
public long getInputCount() {
|
||||
return inputCount;
|
||||
}
|
||||
|
||||
public int getEmitCount() {
|
||||
public long getEmitCount() {
|
||||
return emitCount;
|
||||
}
|
||||
|
||||
public int getOutputCount() {
|
||||
public long getOutputCount() {
|
||||
return outputCount;
|
||||
}
|
||||
|
||||
@@ -59,12 +71,15 @@ public class MapReduceCounts {
|
||||
*/
|
||||
@Override
|
||||
public int hashCode() {
|
||||
|
||||
final int prime = 31;
|
||||
int result = 1;
|
||||
long result = 1;
|
||||
|
||||
result = prime * result + emitCount;
|
||||
result = prime * result + inputCount;
|
||||
result = prime * result + outputCount;
|
||||
return result;
|
||||
|
||||
return Long.valueOf(result).intValue();
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -118,15 +118,14 @@ public class MapReduceResults<T> implements Iterable<T> {
|
||||
DBObject counts = (DBObject) rawResults.get("counts");
|
||||
|
||||
if (counts == null) {
|
||||
return new MapReduceCounts(-1, -1, -1);
|
||||
return MapReduceCounts.NONE;
|
||||
}
|
||||
|
||||
if (counts.get("input") != null && counts.get("emit") != null && counts.get("output") != null) {
|
||||
return new MapReduceCounts((Integer) counts.get("input"), (Integer) counts.get("emit"),
|
||||
(Integer) counts.get("output"));
|
||||
return new MapReduceCounts(getAsLong(counts, "input"), getAsLong(counts, "emit"), getAsLong(counts, "output"));
|
||||
}
|
||||
|
||||
return new MapReduceCounts(-1, -1, -1);
|
||||
return MapReduceCounts.NONE;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
/**
|
||||
* Support for MongoDB map-reduce operations.
|
||||
*/
|
||||
package org.springframework.data.mongodb.core.mapreduce;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2010-2011 the original author or authors.
|
||||
* Copyright 2010-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.
|
||||
@@ -18,14 +18,15 @@ package org.springframework.data.mongodb.core.query;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.springframework.util.ObjectUtils;
|
||||
|
||||
import com.mongodb.BasicDBObject;
|
||||
import com.mongodb.DBObject;
|
||||
|
||||
public class Field {
|
||||
|
||||
private Map<String, Integer> criteria = new HashMap<String, Integer>();
|
||||
|
||||
private Map<String, Object> slices = new HashMap<String, Object>();
|
||||
private final Map<String, Integer> criteria = new HashMap<String, Integer>();
|
||||
private final Map<String, Object> slices = new HashMap<String, Object>();
|
||||
|
||||
public Field include(String key) {
|
||||
criteria.put(key, Integer.valueOf(1));
|
||||
@@ -50,11 +51,54 @@ public class Field {
|
||||
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)));
|
||||
}
|
||||
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;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
* (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.slices);
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2011 the original author or authors.
|
||||
* 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.
|
||||
@@ -15,6 +15,7 @@
|
||||
*/
|
||||
package org.springframework.data.mongodb.core.query;
|
||||
|
||||
import org.springframework.data.mongodb.core.geo.CustomMetric;
|
||||
import org.springframework.data.mongodb.core.geo.Distance;
|
||||
import org.springframework.data.mongodb.core.geo.Metric;
|
||||
import org.springframework.data.mongodb.core.geo.Metrics;
|
||||
@@ -31,10 +32,12 @@ import com.mongodb.DBObject;
|
||||
*/
|
||||
public class NearQuery {
|
||||
|
||||
private final DBObject criteria;
|
||||
private final Point point;
|
||||
private Query query;
|
||||
private Double maxDistance;
|
||||
private Distance maxDistance;
|
||||
private Metric metric;
|
||||
private boolean spherical;
|
||||
private Integer num;
|
||||
|
||||
/**
|
||||
* Creates a new {@link NearQuery}.
|
||||
@@ -45,13 +48,11 @@ public class NearQuery {
|
||||
|
||||
Assert.notNull(point);
|
||||
|
||||
this.criteria = new BasicDBObject();
|
||||
this.criteria.put("near", point.asList());
|
||||
this.point = point;
|
||||
this.spherical = false;
|
||||
|
||||
this.metric = metric;
|
||||
if (metric != null) {
|
||||
spherical(true);
|
||||
distanceMultiplier(metric);
|
||||
in(metric);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -105,12 +106,13 @@ public class NearQuery {
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the {@link Metric} underlying the actual query.
|
||||
* Returns the {@link Metric} underlying the actual query. If no metric was set explicitly {@link Metrics#NEUTRAL}
|
||||
* will be returned.
|
||||
*
|
||||
* @return
|
||||
* @return will never be {@literal null}.
|
||||
*/
|
||||
public Metric getMetric() {
|
||||
return metric;
|
||||
return metric == null ? Metrics.NEUTRAL : metric;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -120,68 +122,96 @@ public class NearQuery {
|
||||
* @return
|
||||
*/
|
||||
public NearQuery num(int num) {
|
||||
this.criteria.put("num", num);
|
||||
this.num = num;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the max distance results shall have from the configured origin. Will normalize the given value using a
|
||||
* potentially already configured {@link Metric}.
|
||||
* Sets the max distance results shall have from the configured origin. If a {@link Metric} was set before the given
|
||||
* value will be interpreted as being a value in that metric. E.g.
|
||||
*
|
||||
* <pre>
|
||||
* NearQuery query = near(10.0, 20.0, Metrics.KILOMETERS).maxDistance(150);
|
||||
* </pre>
|
||||
*
|
||||
* Will set the maximum distance to 150 kilometers.
|
||||
*
|
||||
* @param maxDistance
|
||||
* @return
|
||||
*/
|
||||
public NearQuery maxDistance(double maxDistance) {
|
||||
this.maxDistance = getNormalizedDistance(maxDistance, this.metric);
|
||||
return this;
|
||||
return maxDistance(new Distance(maxDistance, getMetric()));
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the maximum distance supplied in a given metric. Will normalize the distance but not reconfigure the query's
|
||||
* {@link Metric}.
|
||||
* result {@link Metric} if one was configured before.
|
||||
*
|
||||
* @param maxDistance
|
||||
* @param metric must not be {@literal null}.
|
||||
* @return
|
||||
*/
|
||||
public NearQuery maxDistance(double maxDistance, Metric metric) {
|
||||
|
||||
Assert.notNull(metric);
|
||||
this.spherical(true);
|
||||
return maxDistance(getNormalizedDistance(maxDistance, metric));
|
||||
return maxDistance(new Distance(maxDistance, metric));
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the maximum distance to the given {@link Distance}.
|
||||
* Sets the maximum distance to the given {@link Distance}. Will set the returned {@link Metric} to be the one of the
|
||||
* given {@link Distance} if no {@link Metric} was set before.
|
||||
*
|
||||
* @param distance
|
||||
* @param distance must not be {@literal null}.
|
||||
* @return
|
||||
*/
|
||||
public NearQuery maxDistance(Distance distance) {
|
||||
|
||||
Assert.notNull(distance);
|
||||
return maxDistance(distance.getValue(), distance.getMetric());
|
||||
|
||||
if (distance.getMetric() != Metrics.NEUTRAL) {
|
||||
this.spherical(true);
|
||||
}
|
||||
|
||||
if (this.metric == null) {
|
||||
in(distance.getMetric());
|
||||
}
|
||||
|
||||
this.maxDistance = distance;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Configures a distance multiplier the resulting distances get applied.
|
||||
* Returns the maximum {@link Distance}.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public Distance getMaxDistance() {
|
||||
return this.maxDistance;
|
||||
}
|
||||
|
||||
/**
|
||||
* Configures a {@link CustomMetric} with the given multiplier.
|
||||
*
|
||||
* @param distanceMultiplier
|
||||
* @return
|
||||
*/
|
||||
public NearQuery distanceMultiplier(double distanceMultiplier) {
|
||||
this.criteria.put("distanceMultiplier", distanceMultiplier);
|
||||
|
||||
this.metric = new CustomMetric(distanceMultiplier);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Configures the distance multiplier to the multiplier of the given {@link Metric}. Does <em>not</em> recalculate the
|
||||
* {@link #maxDistance(double)}.
|
||||
* Configures the distance multiplier to the multiplier of the given {@link Metric}.
|
||||
*
|
||||
* @deprecated use {@link #in(Metric)} instead.
|
||||
* @param metric must not be {@literal null}.
|
||||
* @return
|
||||
*/
|
||||
@Deprecated
|
||||
public NearQuery distanceMultiplier(Metric metric) {
|
||||
Assert.notNull(metric);
|
||||
return distanceMultiplier(metric.getMultiplier());
|
||||
return in(metric);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -191,10 +221,19 @@ public class NearQuery {
|
||||
* @return
|
||||
*/
|
||||
public NearQuery spherical(boolean spherical) {
|
||||
this.criteria.put("spherical", spherical);
|
||||
this.spherical = spherical;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether spharical values will be returned.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public boolean isSpherical() {
|
||||
return this.spherical;
|
||||
}
|
||||
|
||||
/**
|
||||
* Will cause the results' distances being returned in kilometers. Sets {@link #distanceMultiplier(double)} and
|
||||
* {@link #spherical(boolean)} accordingly.
|
||||
@@ -215,6 +254,18 @@ public class NearQuery {
|
||||
return adaptMetric(Metrics.MILES);
|
||||
}
|
||||
|
||||
/**
|
||||
* Will cause the results' distances being returned in the given metric. Sets {@link #distanceMultiplier(double)}
|
||||
* accordingly as well as {@link #spherical(boolean)} if the given {@link Metric} is not {@link Metrics#NEUTRAL}.
|
||||
*
|
||||
* @param metric the metric the results shall be returned in. Uses {@link Metrics#NEUTRAL} if {@literal null} is
|
||||
* passed.
|
||||
* @return
|
||||
*/
|
||||
public NearQuery in(Metric metric) {
|
||||
return adaptMetric(metric == null ? Metrics.NEUTRAL : metric);
|
||||
}
|
||||
|
||||
/**
|
||||
* Configures the given {@link Metric} to be used as base on for this query and recalculate the maximum distance if no
|
||||
* metric was set before.
|
||||
@@ -223,12 +274,12 @@ public class NearQuery {
|
||||
*/
|
||||
private NearQuery adaptMetric(Metric metric) {
|
||||
|
||||
if (this.metric == null && maxDistance != null) {
|
||||
maxDistance(this.maxDistance, metric);
|
||||
if (metric != Metrics.NEUTRAL) {
|
||||
spherical(true);
|
||||
}
|
||||
|
||||
spherical(true);
|
||||
return distanceMultiplier(metric);
|
||||
this.metric = metric;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -249,18 +300,27 @@ public class NearQuery {
|
||||
*/
|
||||
public DBObject toDBObject() {
|
||||
|
||||
BasicDBObject dbObject = new BasicDBObject(criteria.toMap());
|
||||
BasicDBObject dbObject = new BasicDBObject();
|
||||
|
||||
if (query != null) {
|
||||
dbObject.put("query", query.getQueryObject());
|
||||
}
|
||||
|
||||
if (maxDistance != null) {
|
||||
dbObject.put("maxDistance", maxDistance);
|
||||
dbObject.put("maxDistance", this.maxDistance.getNormalizedValue());
|
||||
}
|
||||
|
||||
if (metric != null) {
|
||||
dbObject.put("distanceMultiplier", metric.getMultiplier());
|
||||
}
|
||||
|
||||
if (num != null) {
|
||||
dbObject.put("num", num);
|
||||
}
|
||||
|
||||
dbObject.put("near", point.asList());
|
||||
dbObject.put("spherical", spherical);
|
||||
|
||||
return dbObject;
|
||||
}
|
||||
|
||||
private double getNormalizedDistance(double distance, Metric metric) {
|
||||
return metric == null ? distance : distance / metric.getMultiplier();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2010-2012 the original author or authors.
|
||||
* Copyright 2010-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.
|
||||
@@ -46,22 +46,33 @@ public class Query {
|
||||
private String hint;
|
||||
|
||||
/**
|
||||
* Static factory method to create a Query using the provided criteria
|
||||
* Static factory method to create a {@link Query} using the provided {@link Criteria}.
|
||||
*
|
||||
* @param critera
|
||||
* @param criteria must not be {@literal null}.
|
||||
* @return
|
||||
*/
|
||||
public static Query query(Criteria critera) {
|
||||
return new Query(critera);
|
||||
public static Query query(Criteria criteria) {
|
||||
return new Query(criteria);
|
||||
}
|
||||
|
||||
public Query() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new {@link Query} using the given {@link Criteria}.
|
||||
*
|
||||
* @param criteria must not be {@literal null}.
|
||||
*/
|
||||
public Query(Criteria criteria) {
|
||||
addCriteria(criteria);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds the given {@link Criteria} to the current {@link Query}.
|
||||
*
|
||||
* @param criteria must not be {@literal null}.
|
||||
* @return
|
||||
*/
|
||||
public Query addCriteria(Criteria criteria) {
|
||||
CriteriaDefinition existing = this.criteria.get(criteria.getKey());
|
||||
String key = criteria.getKey();
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2010-2012 the original author or authors.
|
||||
* Copyright 2010-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.
|
||||
@@ -52,7 +52,10 @@ public class Update {
|
||||
|
||||
/**
|
||||
* Creates an {@link Update} instance from the given {@link DBObject}. Allows to explicitly exlude fields from making
|
||||
* it into the created {@link Update} object.
|
||||
* it into the created {@link Update} object. Note, that this will set attributes directly and <em>not</em> use
|
||||
* {@literal $set}. This means fields not given in the {@link DBObject} will be nulled when executing the update. To
|
||||
* create an only-updating {@link Update} instance of a {@link DBObject}, call {@link #set(String, Object)} for each
|
||||
* value in it.
|
||||
*
|
||||
* @param object the source {@link DBObject} to create the update from.
|
||||
* @param exclude the fields to exclude.
|
||||
@@ -69,7 +72,7 @@ public class Update {
|
||||
continue;
|
||||
}
|
||||
|
||||
update.set(key, object.get(key));
|
||||
update.modifierOps.put(key, object.get(key));
|
||||
}
|
||||
|
||||
return update;
|
||||
@@ -160,7 +163,7 @@ public class Update {
|
||||
* @return
|
||||
*/
|
||||
public Update pop(String key, Position pos) {
|
||||
addMultiFieldOperation("$pop", key, (pos == Position.FIRST ? -1 : 1));
|
||||
addMultiFieldOperation("$pop", key, pos == Position.FIRST ? -1 : 1);
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -214,22 +217,23 @@ public class Update {
|
||||
return dbo;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
protected void addMultiFieldOperation(String operator, String key, Object value) {
|
||||
|
||||
Object existingValue = this.modifierOps.get(operator);
|
||||
LinkedHashMap<String, Object> keyValueMap;
|
||||
DBObject keyValueMap;
|
||||
|
||||
if (existingValue == null) {
|
||||
keyValueMap = new LinkedHashMap<String, Object>();
|
||||
keyValueMap = new BasicDBObject();
|
||||
this.modifierOps.put(operator, keyValueMap);
|
||||
} else {
|
||||
if (existingValue instanceof LinkedHashMap) {
|
||||
keyValueMap = (LinkedHashMap<String, Object>) existingValue;
|
||||
if (existingValue instanceof BasicDBObject) {
|
||||
keyValueMap = (BasicDBObject) existingValue;
|
||||
} else {
|
||||
throw new InvalidDataAccessApiUsageException("Modifier Operations should be a LinkedHashMap but was "
|
||||
+ existingValue.getClass());
|
||||
}
|
||||
}
|
||||
|
||||
keyValueMap.put(key, value);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2011 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.
|
||||
@@ -30,6 +30,7 @@ import com.mongodb.gridfs.GridFSFile;
|
||||
* Collection of operations to store and read files from MongoDB GridFS.
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
* @author Philipp Schneider
|
||||
*/
|
||||
public interface GridFsOperations extends ResourcePatternResolver {
|
||||
|
||||
@@ -42,27 +43,60 @@ public interface GridFsOperations extends ResourcePatternResolver {
|
||||
*/
|
||||
GridFSFile store(InputStream content, String filename);
|
||||
|
||||
/**
|
||||
* Stores the given content into a file with the given name and content type.
|
||||
*
|
||||
* @param content must not be {@literal null}.
|
||||
* @param filename must not be {@literal null} or empty.
|
||||
* @param contentType can be {@literal null}.
|
||||
* @return the {@link GridFSFile} just created
|
||||
*/
|
||||
GridFSFile store(InputStream content, String filename, String contentType);
|
||||
|
||||
/**
|
||||
* Stores the given content into a file with the given name using the given metadata. The metadata object will be
|
||||
* marshalled before writing.
|
||||
*
|
||||
* @param content must not be {@literal null}.
|
||||
* @param filename must not be {@literal null} or empty.
|
||||
* @param metadata
|
||||
* @param metadata can be {@literal null}.
|
||||
* @return the {@link GridFSFile} just created
|
||||
*/
|
||||
GridFSFile store(InputStream content, String filename, Object metadata);
|
||||
|
||||
/**
|
||||
* Stores the given content into a file with the given name and content type using the given metadata. The metadata
|
||||
* object will be marshalled before writing.
|
||||
*
|
||||
* @param content must not be {@literal null}.
|
||||
* @param filename must not be {@literal null} or empty.
|
||||
* @param contentType can be {@literal null}.
|
||||
* @param metadata can be {@literal null}
|
||||
* @return the {@link GridFSFile} just created
|
||||
*/
|
||||
GridFSFile store(InputStream content, String filename, String contentType, Object metadata);
|
||||
|
||||
/**
|
||||
* Stores the given content into a file with the given name using the given metadata.
|
||||
*
|
||||
* @param content must not be {@literal null}.
|
||||
* @param filename must not be {@literal null} or empty.
|
||||
* @param metadata must not be {@literal null}.
|
||||
* @param metadata can be {@literal null}.
|
||||
* @return the {@link GridFSFile} just created
|
||||
*/
|
||||
GridFSFile store(InputStream content, String filename, DBObject metadata);
|
||||
|
||||
/**
|
||||
* Stores the given content into a file with the given name and content type using the given metadata.
|
||||
*
|
||||
* @param content must not be {@literal null}.
|
||||
* @param filename must not be {@literal null} or empty.
|
||||
* @param contentType can be {@literal null}.
|
||||
* @param metadata can be {@literal null}.
|
||||
* @return the {@link GridFSFile} just created
|
||||
*/
|
||||
GridFSFile store(InputStream content, String filename, String contentType, DBObject metadata);
|
||||
|
||||
/**
|
||||
* Returns all files matching the given query. Note, that currently {@link Sort} criterias defined at the
|
||||
* {@link Query} will not be regarded as MongoDB does not support ordering for GridFS file access.
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2011 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.
|
||||
@@ -42,6 +42,7 @@ import com.mongodb.gridfs.GridFSInputFile;
|
||||
* {@link GridFsOperations} implementation to store content into MongoDB GridFS.
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
* @author Philipp Schneider
|
||||
*/
|
||||
public class GridFsTemplate implements GridFsOperations, ResourcePatternResolver {
|
||||
|
||||
@@ -87,15 +88,37 @@ public class GridFsTemplate implements GridFsOperations, ResourcePatternResolver
|
||||
return store(content, filename, (Object) null);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.mongodb.gridfs.GridFsOperations#store(java.io.InputStream, java.lang.String, java.lang.String)
|
||||
*/
|
||||
public GridFSFile store(InputStream content, String filename, String contentType) {
|
||||
return store(content, filename, contentType, (Object) null);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.mongodb.gridfs.GridFsOperations#store(java.io.InputStream, java.lang.String, java.lang.Object)
|
||||
*/
|
||||
public GridFSFile store(InputStream content, String filename, Object metadata) {
|
||||
|
||||
DBObject dbObject = new BasicDBObject();
|
||||
converter.write(metadata, dbObject);
|
||||
return store(content, filename, dbObject);
|
||||
return store(content, filename, null, metadata);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.mongodb.gridfs.GridFsOperations#store(java.io.InputStream, java.lang.String, java.lang.String, java.lang.Object)
|
||||
*/
|
||||
public GridFSFile store(InputStream content, String filename, String contentType, Object metadata) {
|
||||
|
||||
DBObject dbObject = null;
|
||||
|
||||
if (metadata != null) {
|
||||
dbObject = new BasicDBObject();
|
||||
converter.write(metadata, dbObject);
|
||||
}
|
||||
|
||||
return store(content, filename, contentType, dbObject);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -103,16 +126,30 @@ public class GridFsTemplate implements GridFsOperations, ResourcePatternResolver
|
||||
* @see org.springframework.data.mongodb.gridfs.GridFsOperations#store(java.io.InputStream, java.lang.String, com.mongodb.DBObject)
|
||||
*/
|
||||
public GridFSFile store(InputStream content, String filename, DBObject metadata) {
|
||||
return this.store(content, filename, null, metadata);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.mongodb.gridfs.GridFsOperations#store(java.io.InputStream, java.lang.String, com.mongodb.DBObject)
|
||||
*/
|
||||
public GridFSFile store(InputStream content, String filename, String contentType, DBObject metadata) {
|
||||
|
||||
Assert.notNull(content);
|
||||
Assert.hasText(filename);
|
||||
Assert.notNull(metadata);
|
||||
|
||||
GridFSInputFile file = getGridFs().createFile(content);
|
||||
file.setFilename(filename);
|
||||
file.setMetaData(metadata);
|
||||
file.save();
|
||||
|
||||
if (metadata != null) {
|
||||
file.setMetaData(metadata);
|
||||
}
|
||||
|
||||
if (contentType != null) {
|
||||
file.setContentType(contentType);
|
||||
}
|
||||
|
||||
file.save();
|
||||
return file;
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
/**
|
||||
* Support for MongoDB GridFS feature.
|
||||
*/
|
||||
package org.springframework.data.mongodb.gridfs;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2011 the original author or authors.
|
||||
* Copyright 2002-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.
|
||||
@@ -15,19 +15,20 @@
|
||||
*/
|
||||
package org.springframework.data.mongodb.monitor;
|
||||
|
||||
import java.net.InetAddress;
|
||||
import java.net.UnknownHostException;
|
||||
|
||||
import com.mongodb.Mongo;
|
||||
import org.springframework.jmx.export.annotation.ManagedMetric;
|
||||
import org.springframework.jmx.export.annotation.ManagedOperation;
|
||||
import org.springframework.jmx.export.annotation.ManagedResource;
|
||||
import org.springframework.jmx.support.MetricType;
|
||||
|
||||
import com.mongodb.Mongo;
|
||||
|
||||
/**
|
||||
* Expose basic server information via JMX
|
||||
*
|
||||
* @author Mark Pollack
|
||||
* @author Thomas Darimont
|
||||
*/
|
||||
@ManagedResource(description = "Server Information")
|
||||
public class ServerInfo extends AbstractMonitor {
|
||||
@@ -36,9 +37,20 @@ public class ServerInfo extends AbstractMonitor {
|
||||
this.mongo = mongo;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the hostname of the used server reported by mongo.
|
||||
*
|
||||
* @return the reported hostname can also be an IP address.
|
||||
* @throws UnknownHostException
|
||||
*/
|
||||
@ManagedOperation(description = "Server host name")
|
||||
public String getHostName() throws UnknownHostException {
|
||||
return InetAddress.getLocalHost().getHostName();
|
||||
|
||||
/*
|
||||
* UnknownHostException is not necessary anymore, but clients could have
|
||||
* called this method in a try..catch(UnknownHostException) already
|
||||
*/
|
||||
return getServerStatus().getServerUsed().getHost();
|
||||
}
|
||||
|
||||
@ManagedMetric(displayName = "Uptime Estimate")
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
/**
|
||||
* Spring Data's MongoDB abstraction.
|
||||
*/
|
||||
package org.springframework.data.mongodb;
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
/**
|
||||
* CDI support for MongoDB specific repository implementation.
|
||||
*/
|
||||
package org.springframework.data.mongodb.repository.cdi;
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
/**
|
||||
* Support infrastructure for the configuration of MongoDB specific repositories.
|
||||
*/
|
||||
package org.springframework.data.mongodb.repository.config;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2010-2012 the original author or authors.
|
||||
* Copyright 2010-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.
|
||||
@@ -254,7 +254,7 @@ public abstract class AbstractMongoQuery implements RepositoryQuery {
|
||||
|
||||
Distance maxDistance = accessor.getMaxDistance();
|
||||
if (maxDistance != null) {
|
||||
nearQuery.maxDistance(maxDistance);
|
||||
nearQuery.maxDistance(maxDistance).in(maxDistance.getMetric());
|
||||
}
|
||||
|
||||
MongoEntityMetadata<?> metadata = method.getEntityInformation();
|
||||
@@ -264,7 +264,13 @@ public abstract class AbstractMongoQuery implements RepositoryQuery {
|
||||
private boolean isListOfGeoResult() {
|
||||
|
||||
TypeInformation<?> returnType = method.getReturnType();
|
||||
return returnType.getType().equals(List.class) && GeoResult.class.equals(returnType.getComponentType());
|
||||
|
||||
if (!returnType.getType().equals(List.class)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
TypeInformation<?> componentType = returnType.getComponentType();
|
||||
return componentType == null ? false : GeoResult.class.equals(componentType.getType());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2010-2012 the original author or authors.
|
||||
* Copyright 2010-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.
|
||||
@@ -268,15 +268,16 @@ 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;
|
||||
case STARTING_WITH:
|
||||
source = "^" + source;
|
||||
break;
|
||||
case ENDING_WITH:
|
||||
source = source + "$";
|
||||
break;
|
||||
case CONTAINING:
|
||||
source = "*" + source + "*";
|
||||
break;
|
||||
default:
|
||||
}
|
||||
|
||||
return source.replaceAll("\\*", ".*");
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
/**
|
||||
* Query derivation mechanism for MongoDB specific repositories.
|
||||
*/
|
||||
package org.springframework.data.mongodb.repository.query;
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
package org.springframework.data.mongodb.repository.support;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
import org.springframework.data.mapping.model.BeanWrapper;
|
||||
import org.springframework.data.mongodb.core.mapping.MongoPersistentEntity;
|
||||
import org.springframework.data.mongodb.core.mapping.MongoPersistentProperty;
|
||||
@@ -57,7 +58,8 @@ public class MappingMongoEntityInformation<T, ID extends Serializable> extends A
|
||||
this.customCollectionName = customCollectionName;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.repository.support.EntityInformation#getId(java.lang.Object)
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
@@ -65,6 +67,10 @@ public class MappingMongoEntityInformation<T, ID extends Serializable> extends A
|
||||
|
||||
MongoPersistentProperty idProperty = entityMetadata.getIdProperty();
|
||||
|
||||
if (idProperty == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
try {
|
||||
return (ID) BeanWrapper.create(entity, null).getProperty(idProperty);
|
||||
} catch (Exception e) {
|
||||
|
||||
@@ -41,8 +41,8 @@ public class MongoRepositoryFactoryBean<T extends Repository<S, ID>, S, ID exten
|
||||
* @param operations the operations to set
|
||||
*/
|
||||
public void setMongoOperations(MongoOperations operations) {
|
||||
|
||||
this.operations = operations;
|
||||
setMappingContext(operations.getConverter().getMappingContext());
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
/**
|
||||
* Support infrastructure for query derivation of MongoDB specific repositories.
|
||||
*/
|
||||
package org.springframework.data.mongodb.repository.support;
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
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.0.xsd=org/springframework/data/mongodb/config/spring-mongo-1.0.xsd
|
||||
http\://www.springframework.org/schema/data/mongo/spring-mongo.xsd=org/springframework/data/mongodb/config/spring-mongo-1.1.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.xsd=org/springframework/data/mongodb/config/spring-mongo-1.2.xsd
|
||||
|
||||
@@ -11,8 +11,7 @@
|
||||
|
||||
<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"
|
||||
schemaLocation="http://www.springframework.org/schema/context/spring-context.xsd" />
|
||||
<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-1.0.xsd" />
|
||||
|
||||
|
||||
@@ -11,8 +11,7 @@
|
||||
|
||||
<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"
|
||||
schemaLocation="http://www.springframework.org/schema/context/spring-context.xsd" />
|
||||
<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" />
|
||||
|
||||
|
||||
@@ -0,0 +1,482 @@
|
||||
<?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: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:schema>
|
||||
@@ -19,8 +19,13 @@ import static org.hamcrest.Matchers.*;
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.data.mongodb.core.mapping.BasicMongoPersistentEntity;
|
||||
import org.springframework.data.mongodb.core.mapping.Document;
|
||||
import org.springframework.data.mongodb.core.mapping.MongoMappingContext;
|
||||
import org.springframework.expression.spel.support.StandardEvaluationContext;
|
||||
import org.springframework.test.util.ReflectionTestUtils;
|
||||
|
||||
import com.mongodb.Mongo;
|
||||
|
||||
@@ -63,6 +68,17 @@ public class AbstractMongoConfigurationUnitTests {
|
||||
assertScanningDisabled(" ");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void lifecycleCallbacksAreInvokedInAppropriateOrder() {
|
||||
|
||||
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(SampleMongoConfiguration.class);
|
||||
MongoMappingContext mappingContext = context.getBean(MongoMappingContext.class);
|
||||
BasicMongoPersistentEntity<?> entity = mappingContext.getPersistentEntity(Entity.class);
|
||||
StandardEvaluationContext spElContext = (StandardEvaluationContext) ReflectionTestUtils.getField(entity, "context");
|
||||
|
||||
assertThat(spElContext.getBeanResolver(), is(notNullValue()));
|
||||
}
|
||||
|
||||
private static void assertScanningDisabled(final String value) throws ClassNotFoundException {
|
||||
|
||||
AbstractMongoConfiguration configuration = new SampleMongoConfiguration() {
|
||||
|
||||
@@ -0,0 +1,68 @@
|
||||
/*
|
||||
* Copyright 2012 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.data.mongodb.config;
|
||||
|
||||
import static org.hamcrest.CoreMatchers.*;
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import org.joda.time.DateTime;
|
||||
import org.junit.Test;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.support.ClassPathXmlApplicationContext;
|
||||
import org.springframework.data.annotation.CreatedDate;
|
||||
import org.springframework.data.annotation.Id;
|
||||
import org.springframework.data.annotation.LastModifiedDate;
|
||||
import org.springframework.data.mongodb.core.mapping.event.BeforeConvertEvent;
|
||||
|
||||
/**
|
||||
* Integration test for the auditing support.
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
public class AuditingIntegrationTests {
|
||||
|
||||
@Test
|
||||
public void enablesAuditingAndSetsPropertiesAccordingly() {
|
||||
|
||||
ApplicationContext context = new ClassPathXmlApplicationContext("auditing.xml", getClass());
|
||||
|
||||
Entity entity = new Entity();
|
||||
BeforeConvertEvent<Entity> event = new BeforeConvertEvent<Entity>(entity);
|
||||
context.publishEvent(event);
|
||||
|
||||
assertThat(entity.created, is(notNullValue()));
|
||||
assertThat(entity.modified, is(entity.created));
|
||||
|
||||
entity.id = 1L;
|
||||
event = new BeforeConvertEvent<Entity>(entity);
|
||||
context.publishEvent(event);
|
||||
|
||||
assertThat(entity.created, is(notNullValue()));
|
||||
assertThat(entity.modified, is(not(entity.created)));
|
||||
}
|
||||
|
||||
class Entity {
|
||||
|
||||
@CreatedDate
|
||||
DateTime created;
|
||||
|
||||
@LastModifiedDate
|
||||
DateTime modified;
|
||||
|
||||
@Id
|
||||
Long id;
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012 the original author or authors.
|
||||
* Copyright 2012-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.
|
||||
@@ -31,6 +31,7 @@ import com.mongodb.ServerAddress;
|
||||
* Unit tests for {@link ServerAddressPropertyEditor}.
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
* @author Thomas Darimont
|
||||
*/
|
||||
public class ServerAddressPropertyEditorUnitTests {
|
||||
|
||||
@@ -70,6 +71,16 @@ public class ServerAddressPropertyEditorUnitTests {
|
||||
assertSingleAddressOfLocalhost(editor.getValue());
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATAMONGO-693
|
||||
*/
|
||||
@Test
|
||||
public void interpretEmptyStringAsNull() {
|
||||
|
||||
editor.setAsText("");
|
||||
assertNull(editor.getValue());
|
||||
}
|
||||
|
||||
private static void assertSingleAddressOfLocalhost(Object result) throws UnknownHostException {
|
||||
|
||||
assertThat(result, is(instanceOf(ServerAddress[].class)));
|
||||
|
||||
@@ -27,7 +27,7 @@ import com.mongodb.WriteConcern;
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
public class StringToWriteConcernConverterUnitTest {
|
||||
public class StringToWriteConcernConverterUnitTests {
|
||||
|
||||
StringToWriteConcernConverter converter = new StringToWriteConcernConverter();
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012 the original author or authors.
|
||||
* Copyright 2012-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.
|
||||
@@ -21,17 +21,21 @@ import static org.junit.Assert.*;
|
||||
import org.junit.Test;
|
||||
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
|
||||
import org.springframework.beans.factory.support.RootBeanDefinition;
|
||||
import org.springframework.data.mongodb.config.ServerAddressPropertyEditor;
|
||||
import org.springframework.data.mongodb.config.WriteConcernPropertyEditor;
|
||||
import org.springframework.test.util.ReflectionTestUtils;
|
||||
|
||||
import com.mongodb.Mongo;
|
||||
import com.mongodb.ServerAddress;
|
||||
import com.mongodb.WriteConcern;
|
||||
|
||||
/**
|
||||
* Integration tests for {@link MongoFactoryBean}.
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
* @author Thomas Darimont
|
||||
*/
|
||||
public class MongoFactoryBeanIntegrationTest {
|
||||
public class MongoFactoryBeanIntegrationTests {
|
||||
|
||||
/**
|
||||
* @see DATAMONGO-408
|
||||
@@ -49,4 +53,22 @@ public class MongoFactoryBeanIntegrationTest {
|
||||
MongoFactoryBean bean = factory.getBean("&factory", MongoFactoryBean.class);
|
||||
assertThat(ReflectionTestUtils.getField(bean, "writeConcern"), is((Object) WriteConcern.SAFE));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATAMONGO-693
|
||||
*/
|
||||
@Test
|
||||
public void createMongoInstanceWithHostAndEmptyReplicaSets() {
|
||||
|
||||
RootBeanDefinition definition = new RootBeanDefinition(MongoFactoryBean.class);
|
||||
definition.getPropertyValues().addPropertyValue("host", "localhost");
|
||||
definition.getPropertyValues().addPropertyValue("replicaPair", "");
|
||||
|
||||
DefaultListableBeanFactory factory = new DefaultListableBeanFactory();
|
||||
factory.registerCustomEditor(ServerAddress.class, ServerAddressPropertyEditor.class);
|
||||
factory.registerBeanDefinition("factory", definition);
|
||||
|
||||
Mongo mongo = factory.getBean(Mongo.class);
|
||||
assertNotNull(mongo);
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2011-2012 the original author or authors.
|
||||
* 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.
|
||||
@@ -17,6 +17,7 @@ package org.springframework.data.mongodb.core;
|
||||
|
||||
import static org.hamcrest.Matchers.*;
|
||||
import static org.junit.Assert.*;
|
||||
import static org.mockito.Mockito.*;
|
||||
import static org.springframework.data.mongodb.core.query.Criteria.*;
|
||||
import static org.springframework.data.mongodb.core.query.Query.*;
|
||||
import static org.springframework.data.mongodb.core.query.Update.*;
|
||||
@@ -30,6 +31,7 @@ import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.bson.types.ObjectId;
|
||||
import org.hamcrest.CoreMatchers;
|
||||
import org.joda.time.DateTime;
|
||||
import org.junit.After;
|
||||
import org.junit.Assert;
|
||||
@@ -42,12 +44,15 @@ import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.core.convert.converter.Converter;
|
||||
import org.springframework.dao.DataAccessException;
|
||||
import org.springframework.dao.DataIntegrityViolationException;
|
||||
import org.springframework.dao.DuplicateKeyException;
|
||||
import org.springframework.dao.InvalidDataAccessApiUsageException;
|
||||
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.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;
|
||||
@@ -55,6 +60,7 @@ import org.springframework.data.mongodb.core.index.Index;
|
||||
import org.springframework.data.mongodb.core.index.Index.Duplicates;
|
||||
import org.springframework.data.mongodb.core.index.IndexField;
|
||||
import org.springframework.data.mongodb.core.index.IndexInfo;
|
||||
import org.springframework.data.mongodb.core.mapping.Field;
|
||||
import org.springframework.data.mongodb.core.mapping.MongoMappingContext;
|
||||
import org.springframework.data.mongodb.core.query.BasicQuery;
|
||||
import org.springframework.data.mongodb.core.query.Criteria;
|
||||
@@ -82,20 +88,18 @@ import com.mongodb.WriteResult;
|
||||
* @author Thomas Risberg
|
||||
* @author Amol Nayak
|
||||
* @author Patryk Wasik
|
||||
* @author Thomas Darimont
|
||||
*/
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
@ContextConfiguration("classpath:infrastructure.xml")
|
||||
public class MongoTemplateTests {
|
||||
|
||||
@Autowired
|
||||
MongoTemplate template;
|
||||
@Autowired
|
||||
MongoDbFactory factory;
|
||||
@Autowired MongoTemplate template;
|
||||
@Autowired MongoDbFactory factory;
|
||||
|
||||
MongoTemplate mappingTemplate;
|
||||
|
||||
@Rule
|
||||
public ExpectedException thrown = ExpectedException.none();
|
||||
@Rule public ExpectedException thrown = ExpectedException.none();
|
||||
|
||||
@Autowired
|
||||
@SuppressWarnings("unchecked")
|
||||
@@ -145,7 +149,10 @@ public class MongoTemplateTests {
|
||||
template.dropCollection(TestClass.class);
|
||||
template.dropCollection(Sample.class);
|
||||
template.dropCollection(MyPerson.class);
|
||||
template.dropCollection(TypeWithFieldAnnotation.class);
|
||||
template.dropCollection(TypeWithDate.class);
|
||||
template.dropCollection("collection");
|
||||
template.dropCollection("personX");
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -272,7 +279,8 @@ public class MongoTemplateTests {
|
||||
} catch (DataIntegrityViolationException e) {
|
||||
assertThat(
|
||||
e.getMessage(),
|
||||
startsWith("Insert list failed: E11000 duplicate key error index: database.person.$_id_ dup key: { : ObjectId"));
|
||||
CoreMatchers
|
||||
.startsWith("Insert list failed: E11000 duplicate key error index: database.person.$_id_ dup key: { : ObjectId"));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -765,8 +773,7 @@ public class MongoTemplateTests {
|
||||
Query q3 = new Query(Criteria.where("age").in(l1, l2));
|
||||
template.find(q3, PersonWithIdPropertyOfTypeObjectId.class);
|
||||
Assert.fail("Should have trown an InvalidDocumentStoreApiUsageException");
|
||||
} catch (InvalidMongoDbApiUsageException e) {
|
||||
}
|
||||
} catch (InvalidMongoDbApiUsageException e) {}
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -949,6 +956,7 @@ public class MongoTemplateTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("deprecation")
|
||||
public void testUsingReadPreference() throws Exception {
|
||||
this.template.execute("readPref", new CollectionCallback<Object>() {
|
||||
public Object doInCollection(DBCollection collection) throws MongoException, DataAccessException {
|
||||
@@ -1318,6 +1326,18 @@ public class MongoTemplateTests {
|
||||
template.save(person);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATAMONGO-617
|
||||
*/
|
||||
@Test
|
||||
public void doesNotFailOnVersionInitForUnversionedEntity() {
|
||||
|
||||
DBObject dbObject = new BasicDBObject();
|
||||
dbObject.put("firstName", "Oliver");
|
||||
|
||||
template.insert(dbObject, template.determineCollectionName(PersonWithVersionPropertyOfTypeInteger.class));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATAMONGO-539
|
||||
*/
|
||||
@@ -1455,6 +1475,199 @@ public class MongoTemplateTests {
|
||||
assertThat(template.find(null, PersonWithIdPropertyOfTypeObjectId.class), is(result));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATAMONGO-620
|
||||
*/
|
||||
@Test
|
||||
public void versionsObjectIntoDedicatedCollection() {
|
||||
|
||||
PersonWithVersionPropertyOfTypeInteger person = new PersonWithVersionPropertyOfTypeInteger();
|
||||
person.firstName = "Dave";
|
||||
|
||||
template.save(person, "personX");
|
||||
assertThat(person.version, is(0));
|
||||
|
||||
template.save(person, "personX");
|
||||
assertThat(person.version, is(1));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATAMONGO-621
|
||||
*/
|
||||
@Test
|
||||
public void correctlySetsLongVersionProperty() {
|
||||
|
||||
PersonWithVersionPropertyOfTypeLong person = new PersonWithVersionPropertyOfTypeLong();
|
||||
person.firstName = "Dave";
|
||||
|
||||
template.save(person);
|
||||
assertThat(person.version, is(0L));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATAMONGO-622
|
||||
*/
|
||||
@Test(expected = DuplicateKeyException.class)
|
||||
public void preventsDuplicateInsert() {
|
||||
|
||||
template.setWriteConcern(WriteConcern.SAFE);
|
||||
|
||||
PersonWithVersionPropertyOfTypeInteger person = new PersonWithVersionPropertyOfTypeInteger();
|
||||
person.firstName = "Dave";
|
||||
|
||||
template.save(person);
|
||||
assertThat(person.version, is(0));
|
||||
|
||||
person.version = null;
|
||||
template.save(person);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATAMONGO-629
|
||||
*/
|
||||
@Test
|
||||
public void countAndFindWithoutTypeInformation() {
|
||||
|
||||
Person person = new Person();
|
||||
template.save(person);
|
||||
|
||||
Query query = query(where("_id").is(person.getId()));
|
||||
String collectionName = template.getCollectionName(Person.class);
|
||||
|
||||
assertThat(template.find(query, HashMap.class, collectionName), hasSize(1));
|
||||
assertThat(template.count(query, collectionName), is(1L));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATAMONGO-571
|
||||
*/
|
||||
@Test
|
||||
public void nullsPropertiesForVersionObjectUpdates() {
|
||||
|
||||
VersionedPerson person = new VersionedPerson();
|
||||
person.firstname = "Dave";
|
||||
person.lastname = "Matthews";
|
||||
|
||||
template.save(person);
|
||||
assertThat(person.id, is(notNullValue()));
|
||||
|
||||
person.lastname = null;
|
||||
template.save(person);
|
||||
|
||||
person = template.findOne(query(where("id").is(person.id)), VersionedPerson.class);
|
||||
assertThat(person.lastname, is(nullValue()));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATAMONGO-571
|
||||
*/
|
||||
@Test
|
||||
public void nullsValuesForUpdatesOfUnversionedEntity() {
|
||||
|
||||
Person person = new Person("Dave");
|
||||
template.save(person);
|
||||
|
||||
person.setFirstName(null);
|
||||
template.save(person);
|
||||
|
||||
person = template.findOne(query(where("id").is(person.getId())), Person.class);
|
||||
assertThat(person.getFirstName(), is(nullValue()));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATAMONGO-651
|
||||
*/
|
||||
@Test
|
||||
public void throwsMongoSpecificExceptionForDataIntegrityViolations() {
|
||||
|
||||
WriteResult result = mock(WriteResult.class);
|
||||
when(result.getError()).thenReturn("ERROR");
|
||||
|
||||
MongoActionOperation operation = MongoActionOperation.INSERT;
|
||||
|
||||
MongoTemplate mongoTemplate = new MongoTemplate(factory);
|
||||
mongoTemplate.setWriteResultChecking(WriteResultChecking.EXCEPTION);
|
||||
|
||||
try {
|
||||
mongoTemplate.handleAnyWriteResultErrors(result, null, operation);
|
||||
fail("Expected MonogoDataIntegrityViolationException!");
|
||||
} catch (MongoDataIntegrityViolationException o_O) {
|
||||
assertThat(o_O.getActionOperation(), is(operation));
|
||||
assertThat(o_O.getWriteResult(), is(result));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @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));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATAMONGO-675
|
||||
*/
|
||||
@Test
|
||||
public void updateConsidersMappingAnnotations() {
|
||||
|
||||
TypeWithFieldAnnotation entity = new TypeWithFieldAnnotation();
|
||||
entity.emailAddress = "old";
|
||||
|
||||
template.save(entity);
|
||||
|
||||
Query query = query(where("_id").is(entity.id));
|
||||
Update update = Update.update("emailAddress", "new");
|
||||
|
||||
FindAndModifyOptions options = new FindAndModifyOptions().returnNew(true);
|
||||
TypeWithFieldAnnotation result = template.findAndModify(query, update, options, TypeWithFieldAnnotation.class);
|
||||
assertThat(result.emailAddress, is("new"));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATAMONGO-671
|
||||
*/
|
||||
@Test
|
||||
public void findsEntityByDateReference() {
|
||||
|
||||
TypeWithDate entity = new TypeWithDate();
|
||||
entity.date = new Date(System.currentTimeMillis() - 10);
|
||||
template.save(entity);
|
||||
|
||||
Query query = query(where("date").lt(new Date()));
|
||||
List<TypeWithDate> result = template.find(query, TypeWithDate.class);
|
||||
|
||||
assertThat(result, hasSize(1));
|
||||
assertThat(result.get(0).date, is(notNullValue()));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATAMONGO-540
|
||||
*/
|
||||
@Test
|
||||
public void findOneAfterUpsertForNonExistingObjectReturnsTheInsertedObject() {
|
||||
|
||||
String idValue = "4711";
|
||||
Query query = new Query(Criteria.where("id").is(idValue));
|
||||
|
||||
String fieldValue = "bubu";
|
||||
Update update = Update.update("field", fieldValue);
|
||||
|
||||
template.upsert(query, update, Sample.class);
|
||||
Sample result = template.findOne(query, Sample.class);
|
||||
|
||||
assertThat(result, is(notNullValue()));
|
||||
assertThat(result.field, is(fieldValue));
|
||||
assertThat(result.id, is(idValue));
|
||||
}
|
||||
|
||||
static class MyId {
|
||||
|
||||
String first;
|
||||
@@ -1463,14 +1676,12 @@ public class MongoTemplateTests {
|
||||
|
||||
static class TypeWithMyId {
|
||||
|
||||
@Id
|
||||
MyId id;
|
||||
@Id MyId id;
|
||||
}
|
||||
|
||||
public static class Sample {
|
||||
|
||||
@Id
|
||||
String id;
|
||||
@Id String id;
|
||||
String field;
|
||||
}
|
||||
|
||||
@@ -1524,4 +1735,22 @@ public class MongoTemplateTests {
|
||||
String state;
|
||||
String city;
|
||||
}
|
||||
|
||||
static class VersionedPerson {
|
||||
|
||||
@Version Long version;
|
||||
String id, firstname, lastname;
|
||||
}
|
||||
|
||||
static class TypeWithFieldAnnotation {
|
||||
|
||||
@Id ObjectId id;
|
||||
@Field("email") String emailAddress;
|
||||
}
|
||||
|
||||
static class TypeWithDate {
|
||||
|
||||
@Id String id;
|
||||
Date date;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
*/
|
||||
package org.springframework.data.mongodb.core;
|
||||
|
||||
import org.springframework.data.mongodb.core.mapping.Version;
|
||||
import org.springframework.data.annotation.Version;
|
||||
|
||||
public class PersonWithVersionPropertyOfTypeInteger {
|
||||
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
/*
|
||||
* Copyright 2012 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.data.mongodb.core;
|
||||
|
||||
import org.springframework.data.annotation.Version;
|
||||
|
||||
public class PersonWithVersionPropertyOfTypeLong {
|
||||
|
||||
String id;
|
||||
String firstName;
|
||||
int age;
|
||||
|
||||
@Version
|
||||
Long version;
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "PersonWithVersionPropertyOfTypeInteger [id=" + id + ", firstName=" + firstName + ", age=" + age
|
||||
+ ", version=" + version + "]";
|
||||
}
|
||||
}
|
||||
@@ -1,64 +0,0 @@
|
||||
package org.springframework.data.mongodb.core;
|
||||
|
||||
public class SomeEnumTest {
|
||||
|
||||
public enum StringEnum {
|
||||
ONE, TWO, FIVE;
|
||||
}
|
||||
|
||||
public enum NumberEnum {
|
||||
ONE(1), TWO(2), FIVE(5);
|
||||
|
||||
private int value;
|
||||
|
||||
public int value() {
|
||||
return value;
|
||||
}
|
||||
|
||||
NumberEnum(int value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private StringEnum stringEnum;
|
||||
|
||||
private NumberEnum numberEnum;
|
||||
|
||||
private String id;
|
||||
|
||||
private String name;
|
||||
|
||||
public StringEnum getStringEnum() {
|
||||
return stringEnum;
|
||||
}
|
||||
|
||||
public void setStringEnum(StringEnum stringEnum) {
|
||||
this.stringEnum = stringEnum;
|
||||
}
|
||||
|
||||
public NumberEnum getNumberEnum() {
|
||||
return numberEnum;
|
||||
}
|
||||
|
||||
public void setNumberEnum(NumberEnum numberEnum) {
|
||||
this.numberEnum = numberEnum;
|
||||
}
|
||||
|
||||
public String getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(String id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2011-2012 the original author or authors.
|
||||
* 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.
|
||||
@@ -45,7 +45,6 @@ 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;
|
||||
@@ -54,6 +53,7 @@ import org.springframework.data.mapping.PropertyPath;
|
||||
import org.springframework.data.mapping.model.MappingException;
|
||||
import org.springframework.data.mapping.model.MappingInstantiationException;
|
||||
import org.springframework.data.mongodb.MongoDbFactory;
|
||||
import org.springframework.data.mongodb.core.mapping.Document;
|
||||
import org.springframework.data.mongodb.core.mapping.Field;
|
||||
import org.springframework.data.mongodb.core.mapping.MongoMappingContext;
|
||||
import org.springframework.data.mongodb.core.mapping.MongoPersistentProperty;
|
||||
@@ -65,6 +65,7 @@ import com.mongodb.BasicDBObject;
|
||||
import com.mongodb.DB;
|
||||
import com.mongodb.DBObject;
|
||||
import com.mongodb.DBRef;
|
||||
import com.mongodb.util.JSON;
|
||||
|
||||
/**
|
||||
* Unit tests for {@link MappingMongoConverter}.
|
||||
@@ -86,7 +87,7 @@ public class MappingMongoConverterUnitTests {
|
||||
|
||||
mappingContext = new MongoMappingContext();
|
||||
mappingContext.setApplicationContext(context);
|
||||
mappingContext.onApplicationEvent(new ContextRefreshedEvent(context));
|
||||
mappingContext.afterPropertiesSet();
|
||||
|
||||
converter = new MappingMongoConverter(factory, mappingContext);
|
||||
converter.afterPropertiesSet();
|
||||
@@ -110,15 +111,7 @@ public class MappingMongoConverterUnitTests {
|
||||
@Test
|
||||
public void convertsJodaTimeTypesCorrectly() {
|
||||
|
||||
List<Converter<?, ?>> converters = new ArrayList<Converter<?, ?>>();
|
||||
converters.add(new LocalDateToDateConverter());
|
||||
converters.add(new DateToLocalDateConverter());
|
||||
|
||||
CustomConversions conversions = new CustomConversions(converters);
|
||||
mappingContext.setSimpleTypeHolder(conversions.getSimpleTypeHolder());
|
||||
|
||||
converter = new MappingMongoConverter(factory, mappingContext);
|
||||
converter.setCustomConversions(conversions);
|
||||
converter.afterPropertiesSet();
|
||||
|
||||
Person person = new Person();
|
||||
@@ -136,15 +129,7 @@ public class MappingMongoConverterUnitTests {
|
||||
@Test
|
||||
public void convertsCustomTypeOnConvertToMongoType() {
|
||||
|
||||
List<Converter<?, ?>> converters = new ArrayList<Converter<?, ?>>();
|
||||
converters.add(new LocalDateToDateConverter());
|
||||
converters.add(new DateToLocalDateConverter());
|
||||
|
||||
CustomConversions conversions = new CustomConversions(converters);
|
||||
mappingContext.setSimpleTypeHolder(conversions.getSimpleTypeHolder());
|
||||
|
||||
converter = new MappingMongoConverter(factory, mappingContext);
|
||||
converter.setCustomConversions(conversions);
|
||||
converter.afterPropertiesSet();
|
||||
|
||||
LocalDate date = new LocalDate();
|
||||
@@ -1323,6 +1308,18 @@ public class MappingMongoConverterUnitTests {
|
||||
converter.write(wrapper, dbObject);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATAMONGO-592
|
||||
*/
|
||||
@Test
|
||||
public void recursivelyConvertsSpELReadValue() {
|
||||
|
||||
DBObject input = (DBObject) JSON
|
||||
.parse("{ \"_id\" : { \"$oid\" : \"50ca271c4566a2b08f2d667a\" }, \"_class\" : \"com.recorder.TestRecorder2$ObjectContainer\", \"property\" : { \"property\" : 100 } }");
|
||||
|
||||
converter.read(ObjectContainer.class, input);
|
||||
}
|
||||
|
||||
static class GenericType<T> {
|
||||
T content;
|
||||
}
|
||||
@@ -1516,6 +1513,38 @@ public class MappingMongoConverterUnitTests {
|
||||
Throwable throwable;
|
||||
}
|
||||
|
||||
@Document
|
||||
static class PrimitiveContainer {
|
||||
|
||||
@Field("property")
|
||||
private final int m_property;
|
||||
|
||||
@PersistenceConstructor
|
||||
public PrimitiveContainer(@Value("#root.property") int a_property) {
|
||||
m_property = a_property;
|
||||
}
|
||||
|
||||
public int property() {
|
||||
return m_property;
|
||||
}
|
||||
}
|
||||
|
||||
@Document
|
||||
static class ObjectContainer {
|
||||
|
||||
@Field("property")
|
||||
private final PrimitiveContainer m_property;
|
||||
|
||||
@PersistenceConstructor
|
||||
public ObjectContainer(@Value("#root.property") PrimitiveContainer a_property) {
|
||||
m_property = a_property;
|
||||
}
|
||||
|
||||
public PrimitiveContainer property() {
|
||||
return m_property;
|
||||
}
|
||||
}
|
||||
|
||||
private class LocalDateToDateConverter implements Converter<LocalDate, Date> {
|
||||
|
||||
public Date convert(LocalDate source) {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2011-2012 the original author or authors.
|
||||
* 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.
|
||||
@@ -25,6 +25,7 @@ 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;
|
||||
@@ -36,6 +37,7 @@ import org.springframework.data.annotation.Id;
|
||||
import org.springframework.data.mongodb.MongoDbFactory;
|
||||
import org.springframework.data.mongodb.core.DBObjectUtils;
|
||||
import org.springframework.data.mongodb.core.Person;
|
||||
import org.springframework.data.mongodb.core.mapping.BasicMongoPersistentEntity;
|
||||
import org.springframework.data.mongodb.core.mapping.DBRef;
|
||||
import org.springframework.data.mongodb.core.mapping.Field;
|
||||
import org.springframework.data.mongodb.core.mapping.MongoMappingContext;
|
||||
@@ -53,6 +55,7 @@ import com.mongodb.QueryBuilder;
|
||||
* Unit tests for {@link QueryMapper}.
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
* @author Patryk Wasik
|
||||
*/
|
||||
@RunWith(MockitoJUnitRunner.class)
|
||||
public class QueryMapperUnitTests {
|
||||
@@ -61,8 +64,7 @@ public class QueryMapperUnitTests {
|
||||
MongoMappingContext context;
|
||||
MappingMongoConverter converter;
|
||||
|
||||
@Mock
|
||||
MongoDbFactory factory;
|
||||
@Mock MongoDbFactory factory;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
@@ -332,7 +334,11 @@ public class QueryMapperUnitTests {
|
||||
DBObject result = mapper.getMappedObject(query.getQueryObject(), context.getPersistentEntity(WithDBRef.class));
|
||||
|
||||
DBObject reference = DBObjectUtils.getAsDBObject(result, "reference");
|
||||
assertThat(reference.containsField("$in"), is(true));
|
||||
|
||||
BasicDBList inClause = getAsDBList(reference, "$in");
|
||||
assertThat(inClause, hasSize(2));
|
||||
assertThat(inClause.get(0), is(instanceOf(com.mongodb.DBRef.class)));
|
||||
assertThat(inClause.get(1), is(instanceOf(com.mongodb.DBRef.class)));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -347,6 +353,91 @@ public class QueryMapperUnitTests {
|
||||
assertThat(object.get("reference"), is(nullValue()));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATAMONGO-629
|
||||
*/
|
||||
@Test
|
||||
public void doesNotMapIdIfNoEntityMetadataAvailable() {
|
||||
|
||||
String id = new ObjectId().toString();
|
||||
Query query = query(where("id").is(id));
|
||||
|
||||
DBObject object = mapper.getMappedObject(query.getQueryObject(), null);
|
||||
|
||||
assertThat(object.containsField("id"), is(true));
|
||||
assertThat(object.get("id"), is((Object) id));
|
||||
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)));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATAMONGO-705
|
||||
*/
|
||||
@Test
|
||||
public void convertsDBRefWithExistsQuery() {
|
||||
|
||||
Query query = query(where("reference").exists(false));
|
||||
|
||||
BasicMongoPersistentEntity<?> entity = context.getPersistentEntity(WithDBRef.class);
|
||||
DBObject mappedObject = mapper.getMappedObject(query.getQueryObject(), entity);
|
||||
|
||||
DBObject reference = getAsDBObject(mappedObject, "reference");
|
||||
assertThat(reference.containsField("$exists"), is(true));
|
||||
assertThat(reference.get("$exists"), is((Object) false));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATAMONGO-706
|
||||
*/
|
||||
@Test
|
||||
public void convertsNestedDBRefsCorrectly() {
|
||||
|
||||
Reference reference = new Reference();
|
||||
reference.id = 5L;
|
||||
|
||||
Query query = query(where("someString").is("foo").andOperator(where("reference").in(reference)));
|
||||
|
||||
BasicMongoPersistentEntity<?> entity = context.getPersistentEntity(WithDBRef.class);
|
||||
DBObject mappedObject = mapper.getMappedObject(query.getQueryObject(), entity);
|
||||
|
||||
assertThat(mappedObject.get("someString"), is((Object) "foo"));
|
||||
|
||||
BasicDBList andClause = getAsDBList(mappedObject, "$and");
|
||||
assertThat(andClause, hasSize(1));
|
||||
|
||||
BasicDBList inClause = getAsDBList(getAsDBObject(getAsDBObject(andClause, 0), "reference"), "$in");
|
||||
assertThat(inClause, hasSize(1));
|
||||
assertThat(inClause.get(0), is(instanceOf(com.mongodb.DBRef.class)));
|
||||
}
|
||||
|
||||
class IdWrapper {
|
||||
Object id;
|
||||
}
|
||||
@@ -359,14 +450,12 @@ public class QueryMapperUnitTests {
|
||||
|
||||
class Sample {
|
||||
|
||||
@Id
|
||||
private String foo;
|
||||
@Id private String foo;
|
||||
}
|
||||
|
||||
class BigIntegerId {
|
||||
|
||||
@Id
|
||||
private BigInteger id;
|
||||
@Id private BigInteger id;
|
||||
}
|
||||
|
||||
enum Enum {
|
||||
@@ -380,14 +469,13 @@ public class QueryMapperUnitTests {
|
||||
|
||||
class CustomizedField {
|
||||
|
||||
@Field("foo")
|
||||
CustomizedField field;
|
||||
@Field("foo") CustomizedField field;
|
||||
}
|
||||
|
||||
class WithDBRef {
|
||||
|
||||
@DBRef
|
||||
Reference reference;
|
||||
String someString;
|
||||
@DBRef Reference reference;
|
||||
}
|
||||
|
||||
class Reference {
|
||||
@@ -399,4 +487,9 @@ public class QueryMapperUnitTests {
|
||||
|
||||
WithDBRef withDbRef;
|
||||
}
|
||||
|
||||
class WithMapDBRef {
|
||||
|
||||
@DBRef Map<String, Sample> mapWithDBRef;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2010-2011 the original author or authors.
|
||||
* Copyright 2010-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.
|
||||
@@ -115,10 +115,12 @@ public class GeoSpatialTests {
|
||||
|
||||
@Test
|
||||
public void geoNear() {
|
||||
NearQuery geoNear = NearQuery.near(-73, 40, Metrics.KILOMETERS).num(10).maxDistance(150);
|
||||
GeoResults<Venue> geoNearResult = template.geoNear(geoNear, Venue.class);
|
||||
|
||||
assertThat(geoNearResult.getContent().size(), is(not(0)));
|
||||
NearQuery geoNear = NearQuery.near(-73, 40, Metrics.KILOMETERS).num(10).maxDistance(150);
|
||||
|
||||
GeoResults<Venue> result = template.geoNear(geoNear, Venue.class);
|
||||
assertThat(result.getContent().size(), is(not(0)));
|
||||
assertThat(result.getAverageDistance().getMetric(), is((Metric) Metrics.KILOMETERS));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
/*
|
||||
* Copyright (c) 2011 by the original author(s).
|
||||
* 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
|
||||
* 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,7 +13,6 @@
|
||||
* 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.*;
|
||||
@@ -37,14 +36,15 @@ 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,7 +53,8 @@ import com.mongodb.Mongo;
|
||||
import com.mongodb.MongoException;
|
||||
|
||||
/**
|
||||
* @author Jon Brisbin <jbrisbin@vmware.com>
|
||||
* @author Jon Brisbin
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
public class MappingTests {
|
||||
|
||||
@@ -78,7 +79,7 @@ public class MappingTests {
|
||||
ApplicationContext applicationContext;
|
||||
Mongo mongo;
|
||||
MongoTemplate template;
|
||||
MongoMappingContext mappingContext;
|
||||
MappingContext<? extends MongoPersistentEntity<?>, MongoPersistentProperty> mappingContext;
|
||||
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
@@ -89,7 +90,7 @@ public class MappingTests {
|
||||
}
|
||||
applicationContext = new ClassPathXmlApplicationContext("/mapping.xml");
|
||||
template = applicationContext.getBean(MongoTemplate.class);
|
||||
mappingContext = (MongoMappingContext) ReflectionTestUtils.getField(template, "mappingContext");
|
||||
mappingContext = template.getConverter().getMappingContext();
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -464,7 +465,7 @@ public class MappingTests {
|
||||
template.insert(p4);
|
||||
|
||||
Query q = query(where("id").in("1", "2"));
|
||||
q.sort().on("id", Order.ASCENDING);
|
||||
q.with(new Sort(Direction.ASC, "id"));
|
||||
List<PersonPojoStringId> people = template.find(q, PersonPojoStringId.class);
|
||||
assertEquals(2, people.size());
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2011 by the original author(s).
|
||||
* Copyright 2011-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.
|
||||
@@ -13,13 +13,12 @@
|
||||
* 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 java.lang.reflect.Field;
|
||||
import java.util.AbstractMap;
|
||||
import java.util.Collections;
|
||||
import java.util.Map;
|
||||
|
||||
@@ -29,9 +28,7 @@ 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;
|
||||
|
||||
@@ -69,15 +66,14 @@ public class MongoMappingContextUnitTests {
|
||||
assertThat(context.getPersistentEntity(DBRef.class), is(nullValue()));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATAMONGO-638
|
||||
*/
|
||||
@Test
|
||||
public void populatesAbstractMappingContextsApplicationCorrectly() {
|
||||
public void doesNotCreatePersistentEntityForAbstractMap() {
|
||||
|
||||
MongoMappingContext context = new MongoMappingContext();
|
||||
context.setApplicationContext(applicationContext);
|
||||
|
||||
Field field = ReflectionUtils.findField(AbstractMappingContext.class, "applicationContext");
|
||||
ReflectionUtils.makeAccessible(field);
|
||||
assertThat(ReflectionUtils.getField(field, context), is(notNullValue()));
|
||||
assertThat(context.getPersistentEntity(AbstractMap.class), is(nullValue()));
|
||||
}
|
||||
|
||||
class ClassWithMultipleIdProperties {
|
||||
|
||||
@@ -0,0 +1,89 @@
|
||||
/*
|
||||
* Copyright 2012 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.data.mongodb.core.mapping.event;
|
||||
|
||||
import static org.mockito.Matchers.*;
|
||||
import static org.mockito.Mockito.*;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.Mockito;
|
||||
import org.mockito.runners.MockitoJUnitRunner;
|
||||
import org.springframework.data.annotation.Id;
|
||||
import org.springframework.data.auditing.IsNewAwareAuditingHandler;
|
||||
import org.springframework.data.mapping.context.MappingContextIsNewStrategyFactory;
|
||||
import org.springframework.data.mongodb.core.mapping.MongoMappingContext;
|
||||
import org.springframework.data.support.IsNewStrategyFactory;
|
||||
|
||||
/**
|
||||
* Unit tests for {@link AuditingEventListener}.
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
@RunWith(MockitoJUnitRunner.class)
|
||||
public class AuditingEventListenerUnitTests {
|
||||
|
||||
IsNewAwareAuditingHandler<Object> handler;
|
||||
|
||||
IsNewStrategyFactory factory;
|
||||
AuditingEventListener listener;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
|
||||
MongoMappingContext mappingContext = new MongoMappingContext();
|
||||
factory = new MappingContextIsNewStrategyFactory(mappingContext);
|
||||
|
||||
handler = spy(new IsNewAwareAuditingHandler<Object>(factory));
|
||||
doNothing().when(handler).markCreated(Mockito.any(Object.class));
|
||||
doNothing().when(handler).markModified(Mockito.any(Object.class));
|
||||
|
||||
listener = new AuditingEventListener(handler);
|
||||
}
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void rejectsNullAuditingHandler() {
|
||||
new AuditingEventListener(null);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void triggersCreationMarkForObjectWithEmptyId() {
|
||||
|
||||
Sample sample = new Sample();
|
||||
listener.onApplicationEvent(new BeforeConvertEvent<Object>(sample));
|
||||
|
||||
verify(handler, times(1)).markCreated(sample);
|
||||
verify(handler, times(0)).markModified(any(Sample.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void triggersModificationMarkForObjectWithSetId() {
|
||||
|
||||
Sample sample = new Sample();
|
||||
sample.id = "id";
|
||||
listener.onApplicationEvent(new BeforeConvertEvent<Object>(sample));
|
||||
|
||||
verify(handler, times(0)).markCreated(any(Sample.class));
|
||||
verify(handler, times(1)).markModified(sample);
|
||||
}
|
||||
|
||||
static class Sample {
|
||||
|
||||
@Id
|
||||
String id;
|
||||
}
|
||||
}
|
||||
@@ -36,7 +36,7 @@ import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
*/
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
@ContextConfiguration
|
||||
public class ValidatingMongoEventListenerTest {
|
||||
public class ValidatingMongoEventListenerTests {
|
||||
|
||||
@Autowired
|
||||
MongoTemplate mongoTemplate;
|
||||
@@ -0,0 +1,57 @@
|
||||
/*
|
||||
* Copyright 2012 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.data.mongodb.core.mapreduce;
|
||||
|
||||
import static org.hamcrest.CoreMatchers.*;
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
/**
|
||||
* Unit tests for {@link MapReduceCounts}.
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
public class MapReduceCountsUnitTests {
|
||||
|
||||
/**
|
||||
* @see DATACMNS-378
|
||||
*/
|
||||
@Test
|
||||
public void equalsForSameNumberValues() {
|
||||
|
||||
MapReduceCounts left = new MapReduceCounts(1L, 1L, 1L);
|
||||
MapReduceCounts right = new MapReduceCounts(1L, 1L, 1L);
|
||||
|
||||
assertThat(left, is(right));
|
||||
assertThat(right, is(left));
|
||||
assertThat(left.hashCode(), is(right.hashCode()));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATACMNS-378
|
||||
*/
|
||||
@Test
|
||||
public void notEqualForDifferentNumberValues() {
|
||||
|
||||
MapReduceCounts left = new MapReduceCounts(1L, 1L, 1L);
|
||||
MapReduceCounts right = new MapReduceCounts(1L, 2L, 1L);
|
||||
|
||||
assertThat(left, is(not(right)));
|
||||
assertThat(right, is(not(left)));
|
||||
assertThat(left.hashCode(), is(not(right.hashCode())));
|
||||
}
|
||||
}
|
||||
@@ -69,4 +69,18 @@ public class MapReduceResultsUnitTests {
|
||||
DBObject source = new BasicDBObject("timing", inner);
|
||||
new MapReduceResults<Object>(Collections.emptyList(), source);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATAMONGO-378
|
||||
*/
|
||||
@Test
|
||||
public void handlesLongResultsForCounts() {
|
||||
|
||||
DBObject inner = new BasicDBObject("input", 1L);
|
||||
inner.put("emit", 1L);
|
||||
inner.put("output", 1);
|
||||
|
||||
DBObject source = new BasicDBObject("counts", inner);
|
||||
new MapReduceResults<Object>(Collections.emptyList(), source);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,49 @@
|
||||
/*
|
||||
* 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().include("foo");
|
||||
Field right = new Field().include("foo");
|
||||
|
||||
assertThat(left, is(right));
|
||||
assertThat(right, is(left));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void differentObjectSetupCreatesEqualField() {
|
||||
|
||||
Field left = new Field().include("foo");
|
||||
Field right = new Field().include("bar");
|
||||
|
||||
assertThat(left, is(not(right)));
|
||||
assertThat(right, is(not(left)));
|
||||
}
|
||||
}
|
||||
@@ -1,17 +1,37 @@
|
||||
/*
|
||||
* 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.core.query;
|
||||
|
||||
import static org.hamcrest.CoreMatchers.*;
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.springframework.data.mongodb.core.geo.Distance;
|
||||
import org.springframework.data.mongodb.core.geo.Metric;
|
||||
import org.springframework.data.mongodb.core.geo.Metrics;
|
||||
|
||||
/**
|
||||
* Unit tests for {@link NearQuery}.
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
public class NearQueryUnitTests {
|
||||
|
||||
private static final Distance ONE_FIFTY_KILOMETERS = new Distance(150, Metrics.KILOMETERS);
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void rejectsNullPoint() {
|
||||
NearQuery.near(null);
|
||||
@@ -22,9 +42,9 @@ public class NearQueryUnitTests {
|
||||
|
||||
NearQuery query = NearQuery.near(2.5, 2.5, Metrics.KILOMETERS).maxDistance(150);
|
||||
|
||||
assertThat((Double) query.toDBObject().get("maxDistance"), is(0.02351783914331097));
|
||||
assertThat((Boolean) query.toDBObject().get("spherical"), is(true));
|
||||
assertThat((Double) query.toDBObject().get("distanceMultiplier"), is(Metrics.KILOMETERS.getMultiplier()));
|
||||
assertThat(query.getMaxDistance(), is(ONE_FIFTY_KILOMETERS));
|
||||
assertThat(query.getMetric(), is((Metric) Metrics.KILOMETERS));
|
||||
assertThat(query.isSpherical(), is(true));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -32,13 +52,27 @@ public class NearQueryUnitTests {
|
||||
|
||||
NearQuery query = NearQuery.near(2.5, 2.5, Metrics.KILOMETERS).maxDistance(150);
|
||||
|
||||
assertThat((Double) query.toDBObject().get("maxDistance"), is(0.02351783914331097));
|
||||
assertThat((Double) query.toDBObject().get("distanceMultiplier"), is(Metrics.KILOMETERS.getMultiplier()));
|
||||
|
||||
query.inMiles();
|
||||
assertThat((Double) query.toDBObject().get("distanceMultiplier"), is(Metrics.MILES.getMultiplier()));
|
||||
assertThat(query.getMetric(), is((Metric) Metrics.MILES));
|
||||
}
|
||||
|
||||
NearQuery.near(2.5, 2.5).maxDistance(150).inKilometers();
|
||||
assertThat((Double) query.toDBObject().get("maxDistance"), is(0.02351783914331097));
|
||||
@Test
|
||||
public void configuresResultMetricCorrectly() {
|
||||
|
||||
NearQuery query = NearQuery.near(2.5, 2.1);
|
||||
assertThat(query.getMetric(), is((Metric) Metrics.NEUTRAL));
|
||||
|
||||
query = query.maxDistance(ONE_FIFTY_KILOMETERS);
|
||||
assertThat(query.getMetric(), is((Metric) Metrics.KILOMETERS));
|
||||
assertThat(query.getMaxDistance(), is(ONE_FIFTY_KILOMETERS));
|
||||
assertThat(query.isSpherical(), is(true));
|
||||
|
||||
query = query.in(Metrics.MILES);
|
||||
assertThat(query.getMetric(), is((Metric) Metrics.MILES));
|
||||
assertThat(query.getMaxDistance(), is(ONE_FIFTY_KILOMETERS));
|
||||
assertThat(query.isSpherical(), is(true));
|
||||
|
||||
query = query.maxDistance(new Distance(200, Metrics.KILOMETERS));
|
||||
assertThat(query.getMetric(), is((Metric) Metrics.MILES));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2011 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.
|
||||
@@ -41,6 +41,7 @@ import com.mongodb.gridfs.GridFSFile;
|
||||
* Integration tests for {@link GridFsTemplate}.
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
* @author Philipp Schneider
|
||||
*/
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
@ContextConfiguration("classpath:gridfs/gridfs.xml")
|
||||
@@ -77,6 +78,19 @@ public class GridFsTemplateIIntegrationTests {
|
||||
assertSame(result.get(0), reference);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATAMONGO-503
|
||||
*/
|
||||
@Test
|
||||
public void storesContentType() throws IOException {
|
||||
|
||||
GridFSFile reference = operations.store(resource.getInputStream(), "foo2.xml", "application/xml");
|
||||
|
||||
List<GridFSDBFile> result = operations.find(query(whereContentType().is("application/xml")));
|
||||
assertThat(result.size(), is(1));
|
||||
assertSame(result.get(0), reference);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void marshalsComplexMetadata() throws IOException {
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2011 the original author or authors.
|
||||
* Copyright 2002-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.
|
||||
@@ -15,28 +15,32 @@
|
||||
*/
|
||||
package org.springframework.data.mongodb.monitor;
|
||||
|
||||
import com.mongodb.Mongo;
|
||||
import static org.hamcrest.Matchers.*;
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import java.net.UnknownHostException;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.data.mongodb.monitor.OperationCounters;
|
||||
import org.springframework.data.mongodb.monitor.ServerInfo;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
import com.mongodb.Mongo;
|
||||
|
||||
/**
|
||||
* This test class assumes that you are already running the MongoDB server.
|
||||
*
|
||||
* @author Mark Pollack
|
||||
* @author Thomas Darimont
|
||||
*/
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
@ContextConfiguration
|
||||
@ContextConfiguration("classpath:infrastructure.xml")
|
||||
public class MongoMonitorIntegrationTests {
|
||||
|
||||
@Autowired
|
||||
Mongo mongo;
|
||||
@Autowired Mongo mongo;
|
||||
|
||||
@Test
|
||||
public void serverInfo() {
|
||||
@@ -45,9 +49,29 @@ public class MongoMonitorIntegrationTests {
|
||||
Assert.isTrue(StringUtils.hasText("1."));
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws UnknownHostException
|
||||
* @see DATAMONGO-685
|
||||
*/
|
||||
@Test
|
||||
public void getHostNameShouldReturnServerNameReportedByMongo() throws UnknownHostException {
|
||||
|
||||
ServerInfo serverInfo = new ServerInfo(mongo);
|
||||
|
||||
String hostName = null;
|
||||
try {
|
||||
hostName = serverInfo.getHostName();
|
||||
} catch (UnknownHostException e) {
|
||||
throw e;
|
||||
}
|
||||
|
||||
assertThat(hostName, is(notNullValue()));
|
||||
assertThat(hostName, is("127.0.0.1"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void operationCounters() {
|
||||
OperationCounters operationCounters = new OperationCounters(mongo);
|
||||
operationCounters.getInsertCount();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,12 +18,16 @@ 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;
|
||||
@@ -35,12 +39,15 @@ 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.index.Indexed;
|
||||
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.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;
|
||||
@@ -60,29 +67,40 @@ import com.mongodb.WriteConcern;
|
||||
public class PerformanceTests {
|
||||
|
||||
private static final String DATABASE_NAME = "performance";
|
||||
private static final int NUMBER_OF_PERSONS = 30000;
|
||||
private static final int NUMBER_OF_PERSONS = 300;
|
||||
private static final int ITERATIONS = 50;
|
||||
private static final StopWatch watch = new StopWatch();
|
||||
private static final Collection<String> IGNORED_WRITE_CONCERNS = Arrays.asList("MAJORITY", "REPLICAS_SAFE",
|
||||
"FSYNC_SAFE", "JOURNAL_SAFE");
|
||||
"FSYNC_SAFE", "FSYNCED", "JOURNAL_SAFE", "JOURNALED", "REPLICA_ACKNOWLEDGED");
|
||||
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();
|
||||
this.operations = new MongoTemplate(new SimpleMongoDbFactory(this.mongo, DATABASE_NAME));
|
||||
|
||||
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);
|
||||
|
||||
MongoRepositoryFactoryBean<PersonRepository, Person, ObjectId> factory = new MongoRepositoryFactoryBean<PersonRepository, Person, ObjectId>();
|
||||
factory.setMongoOperations(operations);
|
||||
factory.setRepositoryInterface(PersonRepository.class);
|
||||
factory.afterPropertiesSet();
|
||||
|
||||
repository = factory.getObject();
|
||||
this.repository = factory.getObject();
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -90,69 +108,137 @@ public class PerformanceTests {
|
||||
executeWithWriteConcerns(new WriteConcernCallback() {
|
||||
public void doWithWriteConcern(String constantName, WriteConcern concern) {
|
||||
writeHeadline("WriteConcern: " + constantName);
|
||||
writingObjectsUsingPlainDriver("Writing %s objects using plain driver");
|
||||
writingObjectsUsingMongoTemplate("Writing %s objects using template");
|
||||
writingObjectsUsingRepositories("Writing %s objects using repository");
|
||||
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)));
|
||||
writeFooter();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
public void writeAndRead() {
|
||||
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 {
|
||||
|
||||
mongo.setWriteConcern(WriteConcern.SAFE);
|
||||
|
||||
for (int i = 3; i > 0; i--) {
|
||||
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++) {
|
||||
|
||||
setupCollections();
|
||||
|
||||
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.WRITE, writingObjectsUsingPlainDriver(numberOfPersons));
|
||||
statistics.registerTime(Api.TEMPLATE, Mode.WRITE, writingObjectsUsingMongoTemplate(numberOfPersons));
|
||||
statistics.registerTime(Api.REPOSITORY, Mode.WRITE, writingObjectsUsingRepositories(numberOfPersons));
|
||||
|
||||
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.READ, readingUsingPlainDriver());
|
||||
statistics.registerTime(Api.TEMPLATE, Mode.READ, readingUsingTemplate());
|
||||
statistics.registerTime(Api.REPOSITORY, Mode.READ, readingUsingRepository());
|
||||
|
||||
writeHeadline("Repositories");
|
||||
writingObjectsUsingRepositories("Writing %s objects using repository");
|
||||
readingUsingRepository("Reading all objects using repository");
|
||||
queryUsingRepository("Executing query using repository");
|
||||
writeFooter();
|
||||
statistics.registerTime(Api.DRIVER, Mode.QUERY, queryUsingPlainDriver());
|
||||
statistics.registerTime(Api.TEMPLATE, Mode.QUERY, queryUsingTemplate());
|
||||
statistics.registerTime(Api.REPOSITORY, Mode.QUERY, queryUsingRepository());
|
||||
|
||||
writeFooter();
|
||||
if (i > 0 && i % (iterations / 10) == 0) {
|
||||
statistics.printResults(i);
|
||||
}
|
||||
}
|
||||
|
||||
statistics.printResults(iterations);
|
||||
}
|
||||
|
||||
private void writeHeadline(String headline) {
|
||||
System.out.println(headline);
|
||||
System.out.println("---------------------------------".substring(0, headline.length()));
|
||||
System.out.println(createUnderline(headline));
|
||||
}
|
||||
|
||||
private void writeFooter() {
|
||||
System.out.println();
|
||||
}
|
||||
|
||||
private void queryUsingTemplate(String template) {
|
||||
executeWatchedWithTimeAndResultSize(template, new WatchCallback<List<Person>>() {
|
||||
private long queryUsingTemplate() {
|
||||
executeWatched(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 void queryUsingRepository(String template) {
|
||||
executeWatchedWithTimeAndResultSize(template, new WatchCallback<List<Person>>() {
|
||||
private long queryUsingRepository() {
|
||||
executeWatched(new WatchCallback<List<Person>>() {
|
||||
public List<Person> doInWatch() {
|
||||
return repository.findByAddressesZipCodeContaining("1");
|
||||
}
|
||||
});
|
||||
|
||||
return watch.getLastTaskTimeMillis();
|
||||
}
|
||||
|
||||
private void executeWithWriteConcerns(WriteConcernCallback callback) {
|
||||
@@ -181,7 +267,7 @@ public class PerformanceTests {
|
||||
for (String collectionName : COLLECTION_NAMES) {
|
||||
DBCollection collection = db.getCollection(collectionName);
|
||||
collection.drop();
|
||||
db.command(getCreateCollectionCommand(collectionName));
|
||||
collection.getDB().command(getCreateCollectionCommand(collectionName));
|
||||
collection.ensureIndex(new BasicDBObject("firstname", -1));
|
||||
collection.ensureIndex(new BasicDBObject("lastname", -1));
|
||||
}
|
||||
@@ -195,38 +281,42 @@ public class PerformanceTests {
|
||||
return dbObject;
|
||||
}
|
||||
|
||||
private void writingObjectsUsingPlainDriver(String template) {
|
||||
private long writingObjectsUsingPlainDriver(int numberOfPersons) {
|
||||
|
||||
final DBCollection collection = mongo.getDB(DATABASE_NAME).getCollection("driver");
|
||||
final List<DBObject> persons = getPersonDBObjects();
|
||||
final List<Person> persons = getPersonObjects(numberOfPersons);
|
||||
|
||||
executeWatchedWithTime(template, new WatchCallback<Void>() {
|
||||
executeWatched(new WatchCallback<Void>() {
|
||||
public Void doInWatch() {
|
||||
for (DBObject person : persons) {
|
||||
collection.save(person);
|
||||
for (Person person : persons) {
|
||||
collection.save(person.toDBObject());
|
||||
}
|
||||
return null;
|
||||
}
|
||||
});
|
||||
|
||||
return watch.getLastTaskTimeMillis();
|
||||
}
|
||||
|
||||
private void writingObjectsUsingRepositories(String template) {
|
||||
private long writingObjectsUsingRepositories(int numberOfPersons) {
|
||||
|
||||
final List<Person> persons = getPersonObjects();
|
||||
final List<Person> persons = getPersonObjects(numberOfPersons);
|
||||
|
||||
executeWatchedWithTime(template, new WatchCallback<Void>() {
|
||||
executeWatched(new WatchCallback<Void>() {
|
||||
public Void doInWatch() {
|
||||
repository.save(persons);
|
||||
return null;
|
||||
}
|
||||
});
|
||||
|
||||
return watch.getLastTaskTimeMillis();
|
||||
}
|
||||
|
||||
private void writingObjectsUsingMongoTemplate(String template) {
|
||||
private long writingObjectsUsingMongoTemplate(int numberOfPersons) {
|
||||
|
||||
final List<Person> persons = getPersonObjects();
|
||||
final List<Person> persons = getPersonObjects(numberOfPersons);
|
||||
|
||||
executeWatchedWithTime(template, new WatchCallback<Void>() {
|
||||
executeWatched(new WatchCallback<Void>() {
|
||||
public Void doInWatch() {
|
||||
for (Person person : persons) {
|
||||
operations.save(person, "template");
|
||||
@@ -234,82 +324,95 @@ public class PerformanceTests {
|
||||
return null;
|
||||
}
|
||||
});
|
||||
|
||||
return watch.getLastTaskTimeMillis();
|
||||
}
|
||||
|
||||
private void readingUsingPlainDriver(String template) {
|
||||
private long readingUsingPlainDriver() {
|
||||
|
||||
final DBCollection collection = mongo.getDB(DATABASE_NAME).getCollection("driver");
|
||||
|
||||
executeWatchedWithTimeAndResultSize(String.format(template, NUMBER_OF_PERSONS), new WatchCallback<List<Person>>() {
|
||||
executeWatched(new WatchCallback<List<Person>>() {
|
||||
public List<Person> doInWatch() {
|
||||
return toPersons(collection.find());
|
||||
return toPersons(mongo.getDB(DATABASE_NAME).getCollection("driver").find());
|
||||
}
|
||||
});
|
||||
|
||||
return watch.getLastTaskTimeMillis();
|
||||
}
|
||||
|
||||
private void readingUsingTemplate(String template) {
|
||||
executeWatchedWithTimeAndResultSize(String.format(template, NUMBER_OF_PERSONS), new WatchCallback<List<Person>>() {
|
||||
private long readingUsingTemplate() {
|
||||
executeWatched(new WatchCallback<List<Person>>() {
|
||||
public List<Person> doInWatch() {
|
||||
return operations.findAll(Person.class, "template");
|
||||
}
|
||||
});
|
||||
|
||||
return watch.getLastTaskTimeMillis();
|
||||
}
|
||||
|
||||
private void readingUsingRepository(String template) {
|
||||
executeWatchedWithTimeAndResultSize(String.format(template, NUMBER_OF_PERSONS), new WatchCallback<List<Person>>() {
|
||||
private long readingUsingRepository() {
|
||||
executeWatched(new WatchCallback<List<Person>>() {
|
||||
public List<Person> doInWatch() {
|
||||
return repository.findAll();
|
||||
}
|
||||
});
|
||||
|
||||
return watch.getLastTaskTimeMillis();
|
||||
}
|
||||
|
||||
private void queryUsingPlainDriver(String template) {
|
||||
private long queryUsingPlainDriver() {
|
||||
|
||||
final DBCollection collection = mongo.getDB(DATABASE_NAME).getCollection("driver");
|
||||
|
||||
executeWatchedWithTimeAndResultSize(template, new WatchCallback<List<Person>>() {
|
||||
executeWatched(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<DBObject> getPersonDBObjects() {
|
||||
private List<Person> getPersonObjects(int numberOfPersons) {
|
||||
|
||||
List<DBObject> result = new ArrayList<DBObject>(NUMBER_OF_PERSONS);
|
||||
List<Person> result = new ArrayList<Person>();
|
||||
|
||||
for (Person person : getPersonObjects()) {
|
||||
result.add(person.toDBObject());
|
||||
}
|
||||
for (int i = 0; i < numberOfPersons; i++) {
|
||||
|
||||
return result;
|
||||
}
|
||||
List<Address> addresses = new ArrayList<Address>();
|
||||
|
||||
private List<Person> getPersonObjects() {
|
||||
for (int a = 0; a < 5; a++) {
|
||||
addresses.add(new Address("zip" + a, "city" + a));
|
||||
}
|
||||
|
||||
List<Person> result = new ArrayList<Person>(NUMBER_OF_PERSONS);
|
||||
Person person = new Person("Firstname" + i, "Lastname" + i, addresses);
|
||||
|
||||
watch.start("Created " + NUMBER_OF_PERSONS + " Persons");
|
||||
for (int o = 0; o < 10; o++) {
|
||||
person.orders.add(new Order(LineItem.generate()));
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
watch.stop();
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private <T> T executeWatched(String template, WatchCallback<T> callback) {
|
||||
private List<DBObject> getPersonDBObjects(int numberOfPersons) {
|
||||
|
||||
watch.start(String.format(template, NUMBER_OF_PERSONS));
|
||||
List<DBObject> dbObjects = new ArrayList<DBObject>(numberOfPersons);
|
||||
|
||||
for (Person person : getPersonObjects(numberOfPersons)) {
|
||||
dbObjects.add(person.toDBObject());
|
||||
}
|
||||
|
||||
return dbObjects;
|
||||
}
|
||||
|
||||
private <T> T executeWatched(WatchCallback<T> callback) {
|
||||
|
||||
watch.start();
|
||||
|
||||
try {
|
||||
return callback.doInWatch();
|
||||
@@ -318,28 +421,6 @@ 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>();
|
||||
@@ -354,10 +435,9 @@ public class PerformanceTests {
|
||||
static class Person {
|
||||
|
||||
ObjectId id;
|
||||
@Indexed
|
||||
final String firstname, lastname;
|
||||
final List<Address> addresses;
|
||||
final Set<Order> orders;
|
||||
String firstname, lastname;
|
||||
List<Address> addresses;
|
||||
Set<Order> orders;
|
||||
|
||||
public Person(String firstname, String lastname, List<Address> addresses) {
|
||||
this.firstname = firstname;
|
||||
@@ -579,11 +659,253 @@ public class PerformanceTests {
|
||||
DBObject toDBObject();
|
||||
}
|
||||
|
||||
private static List<DBObject> writeAll(Collection<? extends Convertible> convertibles) {
|
||||
List<DBObject> result = new ArrayList<DBObject>();
|
||||
private static BasicDBList writeAll(Collection<? extends Convertible> convertibles) {
|
||||
BasicDBList result = new BasicDBList();
|
||||
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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -38,6 +38,7 @@ import org.springframework.data.mongodb.core.geo.Circle;
|
||||
import org.springframework.data.mongodb.core.geo.Distance;
|
||||
import org.springframework.data.mongodb.core.geo.GeoPage;
|
||||
import org.springframework.data.mongodb.core.geo.GeoResults;
|
||||
import org.springframework.data.mongodb.core.geo.Metric;
|
||||
import org.springframework.data.mongodb.core.geo.Metrics;
|
||||
import org.springframework.data.mongodb.core.geo.Point;
|
||||
import org.springframework.data.mongodb.core.geo.Polygon;
|
||||
@@ -52,11 +53,9 @@ import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
public abstract class AbstractPersonRepositoryIntegrationTests {
|
||||
|
||||
@Autowired
|
||||
protected PersonRepository repository;
|
||||
@Autowired protected PersonRepository repository;
|
||||
|
||||
@Autowired
|
||||
MongoOperations operations;
|
||||
@Autowired MongoOperations operations;
|
||||
|
||||
Person dave, oliver, carter, boyd, stefan, leroi, alicia;
|
||||
QPerson person;
|
||||
@@ -401,6 +400,9 @@ public abstract class AbstractPersonRepositoryIntegrationTests {
|
||||
GeoPage<Person> results = repository.findByLocationNear(new Point(-73.99, 40.73), new Distance(2000,
|
||||
Metrics.KILOMETERS), new PageRequest(0, 20));
|
||||
assertThat(results.getContent().isEmpty(), is(false));
|
||||
|
||||
// DATAMONGO-607
|
||||
assertThat(results.getAverageDistance().getMetric(), is((Metric) Metrics.KILOMETERS));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -542,4 +544,26 @@ public abstract class AbstractPersonRepositoryIntegrationTests {
|
||||
assertThat(result, hasSize(1));
|
||||
assertThat(result, hasItem(dave));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATAMONGO-701
|
||||
*/
|
||||
@Test
|
||||
public void executesDerivedStartsWithQueryCorrectly() {
|
||||
|
||||
List<Person> result = repository.findByLastnameStartsWith("Matt");
|
||||
assertThat(result, hasSize(2));
|
||||
assertThat(result, hasItems(dave, oliver));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATAMONGO-701
|
||||
*/
|
||||
@Test
|
||||
public void executesDerivedEndsWithQueryCorrectly() {
|
||||
|
||||
List<Person> result = repository.findByLastnameEndsWith("thews");
|
||||
assertThat(result, hasSize(2));
|
||||
assertThat(result, hasItems(dave, oliver));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -47,6 +47,10 @@ public interface PersonRepository extends MongoRepository<Person, String>, Query
|
||||
*/
|
||||
List<Person> findByLastname(String lastname);
|
||||
|
||||
List<Person> findByLastnameStartsWith(String prefix);
|
||||
|
||||
List<Person> findByLastnameEndsWith(String postfix);
|
||||
|
||||
/**
|
||||
* Returns all {@link Person}s with the given lastname ordered by their firstname.
|
||||
*
|
||||
|
||||
@@ -1,16 +1,37 @@
|
||||
/*
|
||||
* Copyright 2012 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.data.mongodb.repository.config;
|
||||
|
||||
import static org.hamcrest.CoreMatchers.*;
|
||||
import static org.hamcrest.Matchers.*;
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.config.BeanDefinition;
|
||||
import org.springframework.beans.factory.support.BeanDefinitionReader;
|
||||
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
|
||||
import org.springframework.beans.factory.xml.XmlBeanDefinitionReader;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.core.io.ClassPathResource;
|
||||
import org.springframework.data.mapping.PersistentEntity;
|
||||
import org.springframework.data.mongodb.core.mapping.MongoPersistentEntity;
|
||||
import org.springframework.data.mongodb.repository.AbstractPersonRepositoryIntegrationTests;
|
||||
import org.springframework.data.mongodb.repository.Person;
|
||||
import org.springframework.data.repository.support.Repositories;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
|
||||
/**
|
||||
@@ -24,6 +45,9 @@ public class MongoNamespaceIntegrationTests extends AbstractPersonRepositoryInte
|
||||
DefaultListableBeanFactory factory;
|
||||
BeanDefinitionReader reader;
|
||||
|
||||
@Autowired
|
||||
ApplicationContext context;
|
||||
|
||||
@Before
|
||||
@Override
|
||||
public void setUp() throws InterruptedException {
|
||||
@@ -39,4 +63,16 @@ public class MongoNamespaceIntegrationTests extends AbstractPersonRepositoryInte
|
||||
BeanDefinition definition = factory.getBeanDefinition("personRepository");
|
||||
assertThat(definition, is(notNullValue()));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATAMONGO-581
|
||||
*/
|
||||
@Test
|
||||
public void exposesPersistentEntity() {
|
||||
|
||||
Repositories repositories = new Repositories(context);
|
||||
PersistentEntity<?, ?> entity = repositories.getPersistentEntity(Person.class);
|
||||
assertThat(entity, is(notNullValue()));
|
||||
assertThat(entity, is(instanceOf(MongoPersistentEntity.class)));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -263,7 +263,7 @@ public class MongoQueryCreatorUnitTests {
|
||||
MongoQueryCreator creator = new MongoQueryCreator(tree, getAccessor(converter, "Matt"), context);
|
||||
Query query = creator.createQuery();
|
||||
|
||||
assertThat(query, is(query(where("foo").regex("Matt.*"))));
|
||||
assertThat(query, is(query(where("foo").regex("^Matt"))));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -276,7 +276,7 @@ public class MongoQueryCreatorUnitTests {
|
||||
MongoQueryCreator creator = new MongoQueryCreator(tree, getAccessor(converter, "ews"), context);
|
||||
Query query = creator.createQuery();
|
||||
|
||||
assertThat(query, is(query(where("foo").regex(".*ews"))));
|
||||
assertThat(query, is(query(where("foo").regex("ews$"))));
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<beans xmlns="http://www.springframework.org/schema/beans"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:mongo="http://www.springframework.org/schema/data/mongo"
|
||||
xsi:schemaLocation="http://www.springframework.org/schema/data/mongo http://www.springframework.org/schema/data/mongo/spring-mongo.xsd
|
||||
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
|
||||
|
||||
<mongo:auditing mapping-context-ref="customMappingContext" />
|
||||
|
||||
<bean id="customMappingContext" class="org.springframework.data.mongodb.core.mapping.MongoMappingContext" />
|
||||
|
||||
</beans>
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user