Compare commits
93 Commits
1.1.0.M2
...
1.2.0.RELE
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
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 | ||
|
|
4b018a9d7d | ||
|
|
ecf15b93e0 | ||
|
|
6323a86560 | ||
|
|
3b0b7315e1 | ||
|
|
4aeba6f92d | ||
|
|
342f9ae837 | ||
|
|
66d98b355e | ||
|
|
cabbe747f8 | ||
|
|
5ff3064acd | ||
|
|
3001e2941f | ||
|
|
9cf72fbdd4 | ||
|
|
cb5144de0f | ||
|
|
4be90e51ae | ||
|
|
6c368d557b | ||
|
|
a8432e13a1 | ||
|
|
05ac139554 | ||
|
|
3661b2981e | ||
|
|
69bd7acf74 | ||
|
|
d882af257f | ||
|
|
c92058a79a | ||
|
|
ed2b576261 | ||
|
|
6744446a48 | ||
|
|
fdecec48b2 | ||
|
|
f1289c46e6 | ||
|
|
aa0b87be57 | ||
|
|
2040f02d07 | ||
|
|
13a69ecdfd | ||
|
|
f0051deff0 | ||
|
|
05a8148084 | ||
|
|
aaa44b3369 | ||
|
|
7f35c4430d | ||
|
|
114489d19a | ||
|
|
eda8200d51 | ||
|
|
b078ea9ceb | ||
|
|
d90b1a0ddd | ||
|
|
737a42e07a | ||
|
|
22d5d4c019 | ||
|
|
7ac1e7b6e1 | ||
|
|
e86ab783f3 | ||
|
|
6fe3e67ecb | ||
|
|
3b78034c55 | ||
|
|
a06a69797f | ||
|
|
8b1557e38c | ||
|
|
fcdc6d0df2 | ||
|
|
83b6cd7f05 | ||
|
|
38a9a6d51d | ||
|
|
5e2f16c678 | ||
|
|
d7ae95a779 | ||
|
|
8fbdf9afbd | ||
|
|
f5a4d78e62 | ||
|
|
1f4264e6a7 | ||
|
|
05baa851d8 | ||
|
|
35e8ae1224 | ||
|
|
ceec0bcc4a | ||
|
|
0d87e7fa5f | ||
|
|
a530629d97 | ||
|
|
ba0232b187 | ||
|
|
04a17cacb7 | ||
|
|
761d725fce | ||
|
|
726b0b1bcc | ||
|
|
888e031452 |
41
README.md
41
README.md
@@ -1,16 +1,22 @@
|
||||
Spring Data - Document
|
||||
Spring Data MongoDB
|
||||
======================
|
||||
|
||||
The primary goal of the [Spring Data](http://www.springsource.org/spring-data) project is to make it easier to build Spring-powered applications that use new data access technologies such as non-relational databases, map-reduce frameworks, and cloud based data services.
|
||||
As the name implies, the **Document** modules provides integration with document databases such as [MongoDB](http://www.mongodb.org/) and [CouchDB](http://couchdb.apache.org/).
|
||||
|
||||
The Spring Data MongoDB aims to provide a familiar and consistent Spring-based programming model for for new datastores while retaining store-specific features and capabilities. The Spring Data MongoDB project provides integration with the MongoDB document database. Key functional areas of Spring Data MongoDB are a POJO centric model for interacting with a MongoDB DBCollection and easily writing a Repository style data access layer
|
||||
|
||||
Getting Help
|
||||
------------
|
||||
|
||||
At this point your best bet is to look at the Look at the [JavaDocs](http://static.springsource.org/spring-data/data-document/docs/1.0.0.BUILD-SNAPSHOT/spring-data-mongodb/apidocs/) for MongoDB integration and corresponding and source code. For more detailed questions, use the [forum](http://forum.springsource.org/forumdisplay.php?f=80). If you are new to Spring as well as to Spring Data, look for information about [Spring projects](http://www.springsource.org/projects).
|
||||
For a comprehensive treatmet of all the Spring Data MongoDB features, please refer to the The [User Guide](http://static.springsource.org/spring-data/data-mongodb/docs/current/reference/html/)
|
||||
|
||||
The [User Guide](http://static.springsource.org/spring-data/data-document/docs/1.0.0.BUILD-SNAPSHOT/reference/html/) (A work in progress).
|
||||
The [JavaDocs](http://static.springsource.org/spring-data/data-mongodb/docs/current/api/) have extensive comments in them as well.
|
||||
|
||||
The home page of [Spring Data MongoDB](http://www.springsource.org/spring-data/mongodb) contains links to articles and other resources.
|
||||
|
||||
For more detailed questions, use the [forum](http://forum.springsource.org/forumdisplay.php?f=80).
|
||||
|
||||
If you are new to Spring as well as to Spring Data, look for information about [Spring projects](http://www.springsource.org/projects).
|
||||
|
||||
|
||||
Quick Start
|
||||
@@ -23,19 +29,19 @@ 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>
|
||||
<dependency>
|
||||
<groupId>org.springframework.data</groupId>
|
||||
<artifactId>spring-data-mongodb</artifactId>
|
||||
<version>1.2.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>
|
||||
<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>
|
||||
|
||||
### MongoTemplate
|
||||
MongoTemplate is the central support class for Mongo database operations. It provides
|
||||
@@ -137,11 +143,6 @@ This will register an object in the container named PersonRepository. You can u
|
||||
}
|
||||
|
||||
|
||||
## CouchDB
|
||||
|
||||
TBD
|
||||
|
||||
|
||||
Contributing to Spring Data
|
||||
---------------------------
|
||||
|
||||
|
||||
366
pom.xml
366
pom.xml
@@ -1,291 +1,93 @@
|
||||
<?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>
|
||||
<version>1.1.0.M2</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.0.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.0.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
|
||||
|
||||
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.type>multi</project.type>
|
||||
<dist.name>spring-data-mongodb</dist.name>
|
||||
<springdata.commons>1.5.0.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>
|
||||
|
||||
<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>
|
||||
<dependencies>
|
||||
<!-- MongoDB -->
|
||||
<dependency>
|
||||
<groupId>org.mongodb</groupId>
|
||||
<artifactId>mongo-java-driver</artifactId>
|
||||
<version>${mongo}</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
</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.0.M2</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.0.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.0.M2</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.0.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>
|
||||
|
||||
@@ -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;
|
||||
@@ -44,7 +44,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;
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
@@ -39,20 +40,55 @@ import com.mongodb.DBCollection;
|
||||
import com.mongodb.DBObject;
|
||||
|
||||
@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.getName());
|
||||
|
||||
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;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@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(String collectionName) {
|
||||
@@ -64,26 +100,8 @@ public class CrossStoreMongoTests {
|
||||
|
||||
@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 +109,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 +132,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 +153,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,7 +180,9 @@ public class CrossStoreMongoTests {
|
||||
return null;
|
||||
}
|
||||
});
|
||||
|
||||
boolean weFound3 = false;
|
||||
|
||||
for (DBObject dbo : this.mongoTemplate.getCollection(Person.class.getName()).find()) {
|
||||
Assert.assertTrue(!dbo.get("_entity_id").equals(2L));
|
||||
if (dbo.get("_entity_id").equals(3L)) {
|
||||
|
||||
@@ -1,12 +0,0 @@
|
||||
log4j.rootCategory=INFO, stdout
|
||||
|
||||
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
|
||||
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
|
||||
log4j.appender.stdout.layout.ConversionPattern=%d{ABSOLUTE} %5p %40.40c:%4L - %m%n
|
||||
|
||||
log4j.category.org.springframework=INFO
|
||||
log4j.category.org.springframework.data=TRACE
|
||||
|
||||
log4j.category.org.hibernate.SQL=DEBUG
|
||||
# for debugging datasource initialization
|
||||
# log4j.category.test.jdbc=DEBUG
|
||||
@@ -0,0 +1,18 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<configuration>
|
||||
|
||||
<appender name="console" class="ch.qos.logback.core.ConsoleAppender">
|
||||
<encoder>
|
||||
<pattern>%d %5p %40.40c:%4L - %m%n</pattern>
|
||||
</encoder>
|
||||
</appender>
|
||||
|
||||
<!--
|
||||
<logger name="org.springframework" level="debug" />
|
||||
-->
|
||||
|
||||
<root level="error">
|
||||
<appender-ref ref="console" />
|
||||
</root>
|
||||
|
||||
</configuration>
|
||||
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"
|
||||
39
spring-data-mongodb-distribution/pom.xml
Normal file
39
spring-data-mongodb-distribution/pom.xml
Normal file
@@ -0,0 +1,39 @@
|
||||
<?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.0.RELEASE</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
<properties>
|
||||
<project.root>${basedir}/..</project.root>
|
||||
<dist.id>spring-data-mongodb</dist.id>
|
||||
<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>
|
||||
@@ -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.0.M2</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.0.RELEASE</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
<properties>
|
||||
<mongo.version>2.3</mongo.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>
|
||||
|
||||
@@ -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,272 +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>
|
||||
<url>http://www.springsource.org/spring-data/mongodb</url>
|
||||
<version>1.1.0.M2</version>
|
||||
<packaging>pom</packaging>
|
||||
<properties>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
<!-- versions for commonly-used dependencies -->
|
||||
<junit.version>4.10</junit.version>
|
||||
<log4j.version>1.2.16</log4j.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.40>4.0.0.RELEASE</org.springframework.version.40>
|
||||
<org.springframework.version.range>[${org.springframework.version.30}, ${org.springframework.version.40})</org.springframework.version.range>
|
||||
<data.commons.version>1.4.0.M1</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>slf4j-log4j12</artifactId>
|
||||
<version>${org.slf4j.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>log4j</groupId>
|
||||
<artifactId>log4j</artifactId>
|
||||
<version>${log4j.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.4</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>
|
||||
</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>
|
||||
</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>
|
||||
</project>
|
||||
@@ -1,95 +1,77 @@
|
||||
<?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.0.M2</version>
|
||||
<relativePath>../spring-data-mongodb-parent/pom.xml</relativePath>
|
||||
<version>1.2.0.RELEASE</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
<artifactId>spring-data-mongodb</artifactId>
|
||||
<name>Spring Data MongoDB</name>
|
||||
|
||||
<properties>
|
||||
<mongo.version>2.7.1</mongo.version>
|
||||
<querydsl.version>2.6.0</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>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<groupId>javax.persistence</groupId>
|
||||
<artifactId>persistence-api</artifactId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
<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>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<groupId>com.google.code.morphia</groupId>
|
||||
<artifactId>morphia</artifactId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.mysema.querydsl</groupId>
|
||||
<artifactId>querydsl-apt</artifactId>
|
||||
<version>${querydsl.version}</version>
|
||||
<version>${querydsl}</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
|
||||
@@ -104,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>
|
||||
@@ -112,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>
|
||||
|
||||
@@ -134,7 +116,7 @@
|
||||
<dependency>
|
||||
<groupId>javax.validation</groupId>
|
||||
<artifactId>validation-api</artifactId>
|
||||
<version>${validation.version}</version>
|
||||
<version>${validation}</version>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
|
||||
@@ -144,44 +126,30 @@
|
||||
<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>
|
||||
<artifactId>maven-apt-plugin</artifactId>
|
||||
<version>1.0.2</version>
|
||||
<version>1.0.4</version>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>com.mysema.querydsl</groupId>
|
||||
<artifactId>querydsl-apt</artifactId>
|
||||
<version>${querydsl}</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
<executions>
|
||||
<execution>
|
||||
<phase>generate-test-sources</phase>
|
||||
@@ -195,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>
|
||||
|
||||
@@ -27,19 +27,22 @@ 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;
|
||||
|
||||
import com.mongodb.Mongo;
|
||||
|
||||
/**
|
||||
* Base class for Spring Data Mongo configuration using JavaConfig.
|
||||
* Base class for Spring Data MongoDB configuration using JavaConfig.
|
||||
*
|
||||
* @author Mark Pollack
|
||||
* @author Oliver Gierke
|
||||
@@ -96,12 +99,16 @@ public abstract class AbstractMongoConfiguration {
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the base package to scan for mapped {@link Document}s.
|
||||
* Return the base package to scan for mapped {@link Document}s. Will return the package name of the configuration
|
||||
* class' (the concrete class, not this one here) by default. So if you have a {@code com.acme.AppConfig} extending
|
||||
* {@link AbstractMongoConfiguration} the base package will be considered {@code com.acme} unless the method is
|
||||
* overriden to implement alternate behaviour.
|
||||
*
|
||||
* @return
|
||||
* @return the base package to scan for mapped {@link Document} classes or {@literal null} to not enable scanning for
|
||||
* entities.
|
||||
*/
|
||||
protected String getMappingBasePackage() {
|
||||
return null;
|
||||
return getClass().getPackage().getName();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -132,6 +139,17 @@ public abstract class AbstractMongoConfiguration {
|
||||
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
|
||||
|
||||
@@ -26,4 +26,6 @@ public abstract class BeanNames {
|
||||
static final String MONGO = "mongo";
|
||||
static final String DB_FACTORY = "mongoDbFactory";
|
||||
static final String VALIDATING_EVENT_LISTENER = "validatingMongoEventListener";
|
||||
static final String IS_NEW_STRATEGY_FACTORY = "isNewStrategyFactory";
|
||||
static final String DEFAULT_CONVERTER_BEAN_NAME = "mappingConverter";
|
||||
}
|
||||
|
||||
@@ -24,12 +24,12 @@ import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import org.springframework.beans.BeanMetadataElement;
|
||||
import org.springframework.beans.factory.BeanDefinitionStoreException;
|
||||
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
|
||||
import org.springframework.beans.factory.config.BeanDefinition;
|
||||
import org.springframework.beans.factory.config.BeanDefinitionHolder;
|
||||
import org.springframework.beans.factory.config.RuntimeBeanReference;
|
||||
import org.springframework.beans.factory.parsing.BeanComponentDefinition;
|
||||
import org.springframework.beans.factory.parsing.CompositeComponentDefinition;
|
||||
import org.springframework.beans.factory.support.AbstractBeanDefinition;
|
||||
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
|
||||
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
|
||||
@@ -38,6 +38,7 @@ import org.springframework.beans.factory.support.ManagedList;
|
||||
import org.springframework.beans.factory.support.ManagedSet;
|
||||
import org.springframework.beans.factory.support.RootBeanDefinition;
|
||||
import org.springframework.beans.factory.xml.AbstractBeanDefinitionParser;
|
||||
import org.springframework.beans.factory.xml.BeanDefinitionParser;
|
||||
import org.springframework.beans.factory.xml.ParserContext;
|
||||
import org.springframework.context.annotation.ClassPathScanningCandidateComponentProvider;
|
||||
import org.springframework.core.convert.converter.Converter;
|
||||
@@ -48,6 +49,8 @@ import org.springframework.core.type.filter.AnnotationTypeFilter;
|
||||
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;
|
||||
@@ -67,25 +70,28 @@ import org.w3c.dom.Element;
|
||||
* @author Oliver Gierke
|
||||
* @author Maciej Walkowiak
|
||||
*/
|
||||
public class MappingMongoConverterParser extends AbstractBeanDefinitionParser {
|
||||
public class MappingMongoConverterParser implements BeanDefinitionParser {
|
||||
|
||||
private static final String BASE_PACKAGE = "base-package";
|
||||
private static final boolean jsr303Present = ClassUtils.isPresent("javax.validation.Validator",
|
||||
MappingMongoConverterParser.class.getClassLoader());
|
||||
|
||||
@Override
|
||||
protected String resolveId(Element element, AbstractBeanDefinition definition, ParserContext parserContext)
|
||||
throws BeanDefinitionStoreException {
|
||||
String id = super.resolveId(element, definition, parserContext);
|
||||
return StringUtils.hasText(id) ? id : "mappingConverter";
|
||||
}
|
||||
/* (non-Javadoc)
|
||||
* @see org.springframework.beans.factory.xml.BeanDefinitionParser#parse(org.w3c.dom.Element, org.springframework.beans.factory.xml.ParserContext)
|
||||
*/
|
||||
public BeanDefinition parse(Element element, ParserContext parserContext) {
|
||||
|
||||
@Override
|
||||
protected AbstractBeanDefinition parseInternal(Element element, ParserContext parserContext) {
|
||||
BeanDefinitionRegistry registry = parserContext.getRegistry();
|
||||
|
||||
String id = element.getAttribute(AbstractBeanDefinitionParser.ID_ATTRIBUTE);
|
||||
id = StringUtils.hasText(id) ? id : "mappingConverter";
|
||||
|
||||
parserContext.pushContainingComponent(new CompositeComponentDefinition("Mapping Mongo Converter", element));
|
||||
|
||||
BeanDefinition conversionsDefinition = getCustomConversions(element, parserContext);
|
||||
String ctxRef = potentiallyCreateMappingContext(element, parserContext, conversionsDefinition);
|
||||
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");
|
||||
@@ -110,18 +116,23 @@ public class MappingMongoConverterParser extends AbstractBeanDefinitionParser {
|
||||
}
|
||||
BeanDefinitionBuilder indexHelperBuilder = BeanDefinitionBuilder
|
||||
.genericBeanDefinition(MongoPersistentEntityIndexCreator.class);
|
||||
indexHelperBuilder.addConstructorArgValue(new RuntimeBeanReference(ctxRef));
|
||||
indexHelperBuilder.addConstructorArgValue(new RuntimeBeanReference(dbFactoryRef));
|
||||
registry.registerBeanDefinition(INDEX_HELPER, indexHelperBuilder.getBeanDefinition());
|
||||
indexHelperBuilder.addConstructorArgReference(ctxRef);
|
||||
indexHelperBuilder.addConstructorArgReference(dbFactoryRef);
|
||||
|
||||
parserContext.registerBeanComponent(new BeanComponentDefinition(indexHelperBuilder.getBeanDefinition(),
|
||||
INDEX_HELPER));
|
||||
}
|
||||
|
||||
BeanDefinition validatingMongoEventListener = potentiallyCreateValidatingMongoEventListener(element, parserContext);
|
||||
|
||||
if (validatingMongoEventListener != null) {
|
||||
registry.registerBeanDefinition(VALIDATING_EVENT_LISTENER, validatingMongoEventListener);
|
||||
parserContext.registerBeanComponent(new BeanComponentDefinition(validatingMongoEventListener,
|
||||
VALIDATING_EVENT_LISTENER));
|
||||
}
|
||||
|
||||
return converterBuilder.getBeanDefinition();
|
||||
parserContext.registerBeanComponent(new BeanComponentDefinition(converterBuilder.getBeanDefinition(), id));
|
||||
parserContext.popAndRegisterContainingComponent();
|
||||
return null;
|
||||
}
|
||||
|
||||
private BeanDefinition potentiallyCreateValidatingMongoEventListener(Element element, ParserContext parserContext) {
|
||||
@@ -135,7 +146,6 @@ public class MappingMongoConverterParser extends AbstractBeanDefinitionParser {
|
||||
RuntimeBeanReference validator = getValidator(builder, parserContext);
|
||||
|
||||
if (validator != null) {
|
||||
|
||||
builder.getRawBeanDefinition().setBeanClass(ValidatingMongoEventListener.class);
|
||||
builder.addConstructorArgValue(validator);
|
||||
|
||||
@@ -157,36 +167,42 @@ public class MappingMongoConverterParser extends AbstractBeanDefinitionParser {
|
||||
validatorDef.setSource(source);
|
||||
validatorDef.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
|
||||
String validatorName = parserContext.getReaderContext().registerWithGeneratedName(validatorDef);
|
||||
parserContext.registerComponent(new BeanComponentDefinition(validatorDef, validatorName));
|
||||
parserContext.registerBeanComponent(new BeanComponentDefinition(validatorDef, validatorName));
|
||||
|
||||
return new RuntimeBeanReference(validatorName);
|
||||
}
|
||||
|
||||
private String potentiallyCreateMappingContext(Element element, ParserContext parserContext,
|
||||
BeanDefinition conversionsDefinition) {
|
||||
static String potentiallyCreateMappingContext(Element element, ParserContext parserContext,
|
||||
BeanDefinition conversionsDefinition, String converterId) {
|
||||
|
||||
String ctxRef = element.getAttribute("mapping-context-ref");
|
||||
if (!StringUtils.hasText(ctxRef)) {
|
||||
BeanDefinitionBuilder mappingContextBuilder = BeanDefinitionBuilder
|
||||
.genericBeanDefinition(MongoMappingContext.class);
|
||||
|
||||
Set<String> classesToAdd = getInititalEntityClasses(element, mappingContextBuilder);
|
||||
if (classesToAdd != null) {
|
||||
mappingContextBuilder.addPropertyValue("initialEntitySet", classesToAdd);
|
||||
}
|
||||
|
||||
if (conversionsDefinition != null) {
|
||||
AbstractBeanDefinition simpleTypesDefinition = new GenericBeanDefinition();
|
||||
simpleTypesDefinition.setFactoryBeanName("customConversions");
|
||||
simpleTypesDefinition.setFactoryMethodName("getSimpleTypeHolder");
|
||||
|
||||
mappingContextBuilder.addPropertyValue("simpleTypeHolder", simpleTypesDefinition);
|
||||
}
|
||||
|
||||
parserContext.getRegistry().registerBeanDefinition(MAPPING_CONTEXT, mappingContextBuilder.getBeanDefinition());
|
||||
ctxRef = MAPPING_CONTEXT;
|
||||
if (StringUtils.hasText(ctxRef)) {
|
||||
return ctxRef;
|
||||
}
|
||||
|
||||
BeanComponentDefinitionBuilder componentDefinitionBuilder = new BeanComponentDefinitionBuilder(element,
|
||||
parserContext);
|
||||
|
||||
BeanDefinitionBuilder mappingContextBuilder = BeanDefinitionBuilder
|
||||
.genericBeanDefinition(MongoMappingContext.class);
|
||||
|
||||
Set<String> classesToAdd = getInititalEntityClasses(element, mappingContextBuilder);
|
||||
if (classesToAdd != null) {
|
||||
mappingContextBuilder.addPropertyValue("initialEntitySet", classesToAdd);
|
||||
}
|
||||
|
||||
if (conversionsDefinition != null) {
|
||||
AbstractBeanDefinition simpleTypesDefinition = new GenericBeanDefinition();
|
||||
simpleTypesDefinition.setFactoryBeanName("customConversions");
|
||||
simpleTypesDefinition.setFactoryMethodName("getSimpleTypeHolder");
|
||||
|
||||
mappingContextBuilder.addPropertyValue("simpleTypeHolder", simpleTypesDefinition);
|
||||
}
|
||||
|
||||
ctxRef = converterId + "." + MAPPING_CONTEXT;
|
||||
|
||||
parserContext.registerBeanComponent(componentDefinitionBuilder.getComponent(mappingContextBuilder, ctxRef));
|
||||
return ctxRef;
|
||||
}
|
||||
|
||||
@@ -224,7 +240,7 @@ public class MappingMongoConverterParser extends AbstractBeanDefinitionParser {
|
||||
AbstractBeanDefinition conversionsBean = conversionsBuilder.getBeanDefinition();
|
||||
conversionsBean.setSource(parserContext.extractSource(element));
|
||||
|
||||
parserContext.getRegistry().registerBeanDefinition("customConversions", conversionsBean);
|
||||
parserContext.registerBeanComponent(new BeanComponentDefinition(conversionsBean, "customConversions"));
|
||||
|
||||
return conversionsBean;
|
||||
}
|
||||
@@ -232,7 +248,7 @@ public class MappingMongoConverterParser extends AbstractBeanDefinitionParser {
|
||||
return null;
|
||||
}
|
||||
|
||||
public Set<String> getInititalEntityClasses(Element element, BeanDefinitionBuilder builder) {
|
||||
private static Set<String> getInititalEntityClasses(Element element, BeanDefinitionBuilder builder) {
|
||||
|
||||
String basePackage = element.getAttribute(BASE_PACKAGE);
|
||||
|
||||
@@ -271,6 +287,19 @@ public class MappingMongoConverterParser extends AbstractBeanDefinitionParser {
|
||||
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-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.
|
||||
@@ -13,59 +13,53 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.data.mongodb.core;
|
||||
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
import com.mongodb.DBObject;
|
||||
import com.mongodb.WriteConcern;
|
||||
|
||||
/**
|
||||
* Represents an action taken against the collection. Used by {@link WriteConcernResolver} to determine a custom
|
||||
* WriteConcern based on this information.
|
||||
*
|
||||
* Properties that will always be not-null are collectionName and defaultWriteConcern. The EntityClass is null only for
|
||||
* the MongoActionOperaton.INSERT_LIST.
|
||||
*
|
||||
* {@link WriteConcern} based on this information.
|
||||
* <ul>
|
||||
* <li>INSERT, SAVE have null query</li>
|
||||
* <li>REMOVE has null document</li>
|
||||
* <li>INSERT_LIST has null entityClass, document, and query</li>
|
||||
* <li>INSERT_LIST has null entityType, document, and query</li>
|
||||
* </ul>
|
||||
*
|
||||
* @author Mark Pollack
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
public class MongoAction {
|
||||
|
||||
private String collectionName;
|
||||
|
||||
private WriteConcern defaultWriteConcern;
|
||||
|
||||
private Class<?> entityClass;
|
||||
|
||||
private MongoActionOperation mongoActionOperation;
|
||||
|
||||
private DBObject query;
|
||||
|
||||
private DBObject document;
|
||||
private final String collectionName;
|
||||
private final WriteConcern defaultWriteConcern;
|
||||
private final Class<?> entityType;
|
||||
private final MongoActionOperation mongoActionOperation;
|
||||
private final DBObject query;
|
||||
private final DBObject document;
|
||||
|
||||
/**
|
||||
* Create an instance of a MongoAction
|
||||
* Create an instance of a {@link MongoAction}.
|
||||
*
|
||||
* @param defaultWriteConcern the default write concern
|
||||
* @param defaultWriteConcern the default write concern.
|
||||
* @param mongoActionOperation action being taken against the collection
|
||||
* @param collectionName the collection name
|
||||
* @param entityClass the POJO that is being operated against
|
||||
* @param collectionName the collection name, must not be {@literal null} or empty.
|
||||
* @param entityType the POJO that is being operated against
|
||||
* @param document the converted DBObject from the POJO or Spring Update object
|
||||
* @param query the converted DBOjbect from the Spring Query object
|
||||
*/
|
||||
public MongoAction(WriteConcern defaultWriteConcern, MongoActionOperation mongoActionOperation,
|
||||
String collectionName, Class<?> entityClass, DBObject document, DBObject query) {
|
||||
super();
|
||||
String collectionName, Class<?> entityType, DBObject document, DBObject query) {
|
||||
|
||||
Assert.hasText(collectionName, "Collection name must not be null or empty!");
|
||||
|
||||
this.defaultWriteConcern = defaultWriteConcern;
|
||||
this.mongoActionOperation = mongoActionOperation;
|
||||
this.collectionName = collectionName;
|
||||
this.entityClass = entityClass;
|
||||
this.entityType = entityType;
|
||||
this.query = query;
|
||||
this.document = document;
|
||||
}
|
||||
@@ -78,8 +72,16 @@ public class MongoAction {
|
||||
return defaultWriteConcern;
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated use {@link #getEntityType()} instead.
|
||||
*/
|
||||
@Deprecated
|
||||
public Class<?> getEntityClass() {
|
||||
return entityClass;
|
||||
return entityType;
|
||||
}
|
||||
|
||||
public Class<?> getEntityType() {
|
||||
return entityType;
|
||||
}
|
||||
|
||||
public MongoActionOperation getMongoActionOperation() {
|
||||
|
||||
@@ -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.
|
||||
@@ -20,8 +20,8 @@ package org.springframework.data.mongodb.core;
|
||||
* for a given mutating operation
|
||||
*
|
||||
* @author Mark Pollack
|
||||
* @author Oliver Gierke
|
||||
* @see MongoAction
|
||||
*
|
||||
*/
|
||||
public enum MongoActionOperation {
|
||||
|
||||
|
||||
@@ -79,21 +79,18 @@ public abstract class MongoDbUtils {
|
||||
|
||||
DbHolder dbHolder = (DbHolder) TransactionSynchronizationManager.getResource(mongo);
|
||||
|
||||
if (dbHolder != null && !dbHolder.isEmpty()) {
|
||||
// Do we have a populated holder and TX sync active?
|
||||
if (dbHolder != null && !dbHolder.isEmpty() && TransactionSynchronizationManager.isSynchronizationActive()) {
|
||||
|
||||
DB db = null;
|
||||
DB db = dbHolder.getDB(databaseName);
|
||||
|
||||
if (TransactionSynchronizationManager.isSynchronizationActive() && dbHolder.doesNotHoldNonDefaultDB()) {
|
||||
// DB found but not yet synchronized
|
||||
if (db != null && !dbHolder.isSynchronizedWithTransaction()) {
|
||||
|
||||
db = dbHolder.getDB(databaseName);
|
||||
LOGGER.debug("Registering Spring transaction synchronization for existing MongoDB {}.", databaseName);
|
||||
|
||||
if (db != null && !dbHolder.isSynchronizedWithTransaction()) {
|
||||
|
||||
LOGGER.debug("Registering Spring transaction synchronization for existing MongoDB {}.", databaseName);
|
||||
|
||||
TransactionSynchronizationManager.registerSynchronization(new MongoSynchronization(dbHolder, mongo));
|
||||
dbHolder.setSynchronizedWithTransaction(true);
|
||||
}
|
||||
TransactionSynchronizationManager.registerSynchronization(new MongoSynchronization(dbHolder, mongo));
|
||||
dbHolder.setSynchronizedWithTransaction(true);
|
||||
}
|
||||
|
||||
if (db != null) {
|
||||
@@ -101,24 +98,27 @@ public abstract class MongoDbUtils {
|
||||
}
|
||||
}
|
||||
|
||||
// Lookup fresh database instance
|
||||
LOGGER.debug("Getting Mongo Database name=[{}]", databaseName);
|
||||
|
||||
DB db = mongo.getDB(databaseName);
|
||||
boolean credentialsGiven = credentials.hasUsername() && credentials.hasPassword();
|
||||
|
||||
if (credentialsGiven && !db.isAuthenticated()) {
|
||||
synchronized (db) {
|
||||
|
||||
String username = credentials.getUsername();
|
||||
String password = credentials.hasPassword() ? credentials.getPassword() : null;
|
||||
if (credentialsGiven && !db.isAuthenticated()) {
|
||||
|
||||
if (!db.authenticate(username, password == null ? null : password.toCharArray())) {
|
||||
throw new CannotGetMongoDbConnectionException("Failed to authenticate to database [" + databaseName
|
||||
+ "], username = [" + username + "], password = [" + password + "]", databaseName, credentials);
|
||||
String username = credentials.getUsername();
|
||||
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 + "], "
|
||||
+ credentials.toString(), databaseName, credentials);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Use same Session for further Mongo actions within the transaction.
|
||||
// Thread object will get removed by synchronization at transaction completion.
|
||||
// TX sync active, bind new database to thread
|
||||
if (TransactionSynchronizationManager.isSynchronizationActive()) {
|
||||
|
||||
LOGGER.debug("Registering Spring transaction synchronization for MongoDB instance {}.", databaseName);
|
||||
@@ -162,7 +162,7 @@ public abstract class MongoDbUtils {
|
||||
return false;
|
||||
}
|
||||
DbHolder dbHolder = (DbHolder) TransactionSynchronizationManager.getResource(mongo);
|
||||
return (dbHolder != null && dbHolder.containsDB(db));
|
||||
return dbHolder != null && dbHolder.containsDB(db);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -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.
|
||||
@@ -15,12 +15,6 @@
|
||||
*/
|
||||
package org.springframework.data.mongodb.core;
|
||||
|
||||
import com.mongodb.MongoException;
|
||||
import com.mongodb.MongoException.CursorNotFound;
|
||||
import com.mongodb.MongoException.DuplicateKey;
|
||||
import com.mongodb.MongoException.Network;
|
||||
import com.mongodb.MongoInternalException;
|
||||
|
||||
import org.springframework.dao.DataAccessException;
|
||||
import org.springframework.dao.DataAccessResourceFailureException;
|
||||
import org.springframework.dao.DuplicateKeyException;
|
||||
@@ -29,21 +23,26 @@ import org.springframework.dao.InvalidDataAccessResourceUsageException;
|
||||
import org.springframework.dao.support.PersistenceExceptionTranslator;
|
||||
import org.springframework.data.mongodb.UncategorizedMongoDbException;
|
||||
|
||||
import com.mongodb.MongoException;
|
||||
import com.mongodb.MongoException.CursorNotFound;
|
||||
import com.mongodb.MongoException.DuplicateKey;
|
||||
import com.mongodb.MongoException.Network;
|
||||
import com.mongodb.MongoInternalException;
|
||||
|
||||
/**
|
||||
* Simple {@link PersistenceExceptionTranslator} for Mongo. Convert the given runtime exception to an appropriate
|
||||
* exception from the {@code org.springframework.dao} hierarchy. Return {@literal null} if no translation is
|
||||
* appropriate: any other exception may have resulted from user code, and should not be translated.
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
* @author Michal Vich
|
||||
*/
|
||||
public class MongoExceptionTranslator implements PersistenceExceptionTranslator {
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see org.springframework.dao.support.PersistenceExceptionTranslator#
|
||||
* translateExceptionIfPossible(java.lang.RuntimeException)
|
||||
*/
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.dao.support.PersistenceExceptionTranslator#translateExceptionIfPossible(java.lang.RuntimeException)
|
||||
*/
|
||||
public DataAccessException translateExceptionIfPossible(RuntimeException ex) {
|
||||
|
||||
// Check for well-known MongoException subclasses.
|
||||
@@ -52,14 +51,23 @@ public class MongoExceptionTranslator implements PersistenceExceptionTranslator
|
||||
if (ex instanceof DuplicateKey) {
|
||||
return new DuplicateKeyException(ex.getMessage(), ex);
|
||||
}
|
||||
|
||||
if (ex instanceof Network) {
|
||||
return new DataAccessResourceFailureException(ex.getMessage(), ex);
|
||||
}
|
||||
|
||||
if (ex instanceof CursorNotFound) {
|
||||
return new DataAccessResourceFailureException(ex.getMessage(), ex);
|
||||
}
|
||||
|
||||
if (ex instanceof MongoInternalException) {
|
||||
return new InvalidDataAccessResourceUsageException(ex.getMessage(), ex);
|
||||
}
|
||||
|
||||
if (ex instanceof MongoException) {
|
||||
|
||||
int code = ((MongoException) ex).getCode();
|
||||
|
||||
if (code == 11000 || code == 11001) {
|
||||
throw new DuplicateKeyException(ex.getMessage(), ex);
|
||||
} else if (code == 12000 || code == 13440) {
|
||||
@@ -69,9 +77,6 @@ public class MongoExceptionTranslator implements PersistenceExceptionTranslator
|
||||
}
|
||||
return new UncategorizedMongoDbException(ex.getMessage(), ex);
|
||||
}
|
||||
if (ex instanceof MongoInternalException) {
|
||||
return new InvalidDataAccessResourceUsageException(ex.getMessage(), ex);
|
||||
}
|
||||
|
||||
// If we get here, we have an exception that resulted from user code,
|
||||
// rather than the persistence provider, so we return null to indicate
|
||||
|
||||
@@ -16,13 +16,14 @@
|
||||
package org.springframework.data.mongodb.core;
|
||||
|
||||
import static org.springframework.data.mongodb.core.query.Criteria.*;
|
||||
import static org.springframework.data.mongodb.core.query.SerializationUtils.*;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
@@ -37,6 +38,7 @@ import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.ApplicationContextAware;
|
||||
import org.springframework.context.ApplicationEventPublisher;
|
||||
import org.springframework.context.ApplicationEventPublisherAware;
|
||||
import org.springframework.context.ApplicationListener;
|
||||
import org.springframework.context.ConfigurableApplicationContext;
|
||||
import org.springframework.core.convert.ConversionService;
|
||||
import org.springframework.core.io.Resource;
|
||||
@@ -44,6 +46,7 @@ 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;
|
||||
import org.springframework.data.convert.EntityReader;
|
||||
import org.springframework.data.mapping.PersistentEntity;
|
||||
@@ -98,6 +101,7 @@ import com.mongodb.ReadPreference;
|
||||
import com.mongodb.WriteConcern;
|
||||
import com.mongodb.WriteResult;
|
||||
import com.mongodb.util.JSON;
|
||||
import com.mongodb.util.JSONParseException;
|
||||
|
||||
/**
|
||||
* Primary implementation of {@link MongoOperations}.
|
||||
@@ -107,40 +111,24 @@ import com.mongodb.util.JSON;
|
||||
* @author Mark Pollack
|
||||
* @author Oliver Gierke
|
||||
* @author Amol Nayak
|
||||
* @author Patryk Wasik
|
||||
*/
|
||||
public class MongoTemplate implements MongoOperations, ApplicationContextAware {
|
||||
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger(MongoTemplate.class);
|
||||
private static final String ID = "_id";
|
||||
private static final String ID_FIELD = "_id";
|
||||
private static final WriteResultChecking DEFAULT_WRITE_RESULT_CHECKING = WriteResultChecking.NONE;
|
||||
@SuppressWarnings("serial")
|
||||
private static final List<String> ITERABLE_CLASSES = new ArrayList<String>() {
|
||||
{
|
||||
add(List.class.getName());
|
||||
add(Collection.class.getName());
|
||||
add(Iterator.class.getName());
|
||||
}
|
||||
};
|
||||
private static final Collection<String> ITERABLE_CLASSES;
|
||||
|
||||
/*
|
||||
* WriteConcern to be used for write operations if it has been specified.
|
||||
* Otherwise we should not use a WriteConcern defaulting to the one set for
|
||||
* the DB or Collection.
|
||||
*/
|
||||
private WriteConcern writeConcern = null;
|
||||
static {
|
||||
|
||||
private WriteConcernResolver writeConcernResolver = new DefaultWriteConcernResolver();
|
||||
Set<String> iterableClasses = new HashSet<String>();
|
||||
iterableClasses.add(List.class.getName());
|
||||
iterableClasses.add(Collection.class.getName());
|
||||
iterableClasses.add(Iterator.class.getName());
|
||||
|
||||
/*
|
||||
* WriteResultChecking to be used for write operations if it has been
|
||||
* specified. Otherwise we should not do any checking.
|
||||
*/
|
||||
private WriteResultChecking writeResultChecking = WriteResultChecking.NONE;
|
||||
|
||||
/**
|
||||
* Set the ReadPreference when operating on a collection. See {@link #prepareCollection(DBCollection)}
|
||||
*/
|
||||
private ReadPreference readPreference = null;
|
||||
ITERABLE_CLASSES = Collections.unmodifiableCollection(iterableClasses);
|
||||
}
|
||||
|
||||
private final MongoConverter mongoConverter;
|
||||
private final MappingContext<? extends MongoPersistentEntity<?>, MongoPersistentProperty> mappingContext;
|
||||
@@ -148,6 +136,10 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware {
|
||||
private final MongoExceptionTranslator exceptionTranslator = new MongoExceptionTranslator();
|
||||
private final QueryMapper mapper;
|
||||
|
||||
private WriteConcern writeConcern;
|
||||
private WriteConcernResolver writeConcernResolver = DefaultWriteConcernResolver.INSTANCE;
|
||||
private WriteResultChecking writeResultChecking = WriteResultChecking.NONE;
|
||||
private ReadPreference readPreference;
|
||||
private ApplicationEventPublisher eventPublisher;
|
||||
private ResourceLoader resourceLoader;
|
||||
private MongoPersistentEntityIndexCreator indexCreator;
|
||||
@@ -155,8 +147,8 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware {
|
||||
/**
|
||||
* Constructor used for a basic template configuration
|
||||
*
|
||||
* @param mongo
|
||||
* @param databaseName
|
||||
* @param mongo must not be {@literal null}.
|
||||
* @param databaseName must not be {@literal null} or empty.
|
||||
*/
|
||||
public MongoTemplate(Mongo mongo, String databaseName) {
|
||||
this(new SimpleMongoDbFactory(mongo, databaseName), null);
|
||||
@@ -166,8 +158,8 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware {
|
||||
* Constructor used for a template configuration with user credentials in the form of
|
||||
* {@link org.springframework.data.authentication.UserCredentials}
|
||||
*
|
||||
* @param mongo
|
||||
* @param databaseName
|
||||
* @param mongo must not be {@literal null}.
|
||||
* @param databaseName must not be {@literal null} or empty.
|
||||
* @param userCredentials
|
||||
*/
|
||||
public MongoTemplate(Mongo mongo, String databaseName, UserCredentials userCredentials) {
|
||||
@@ -175,9 +167,9 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware {
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor used for a basic template configuration
|
||||
* Constructor used for a basic template configuration.
|
||||
*
|
||||
* @param mongoDbFactory
|
||||
* @param mongoDbFactory must not be {@literal null}.
|
||||
*/
|
||||
public MongoTemplate(MongoDbFactory mongoDbFactory) {
|
||||
this(mongoDbFactory, null);
|
||||
@@ -186,7 +178,7 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware {
|
||||
/**
|
||||
* Constructor used for a basic template configuration.
|
||||
*
|
||||
* @param mongoDbFactory
|
||||
* @param mongoDbFactory must not be {@literal null}.
|
||||
* @param mongoConverter
|
||||
*/
|
||||
public MongoTemplate(MongoDbFactory mongoDbFactory, MongoConverter mongoConverter) {
|
||||
@@ -207,7 +199,6 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware {
|
||||
((ApplicationEventPublisherAware) mappingContext).setApplicationEventPublisher(eventPublisher);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -221,7 +212,9 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware {
|
||||
}
|
||||
|
||||
/**
|
||||
* Configures the {@link WriteConcern} to be used with the template.
|
||||
* Configures the {@link WriteConcern} to be used with the template. If none is configured the {@link WriteConcern}
|
||||
* configured on the {@link MongoDbFactory} will apply. If you configured a {@link Mongo} instance no
|
||||
* {@link WriteConcern} will be used.
|
||||
*
|
||||
* @param writeConcern
|
||||
*/
|
||||
@@ -248,11 +241,14 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware {
|
||||
this.readPreference = readPreference;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.context.ApplicationContextAware#setApplicationContext(org.springframework.context.ApplicationContext)
|
||||
*/
|
||||
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
|
||||
String[] beans = applicationContext.getBeanNamesForType(MongoPersistentEntityIndexCreator.class);
|
||||
if ((null == beans || beans.length == 0) && applicationContext instanceof ConfigurableApplicationContext) {
|
||||
((ConfigurableApplicationContext) applicationContext).addApplicationListener(indexCreator);
|
||||
}
|
||||
|
||||
prepareIndexCreator(applicationContext);
|
||||
|
||||
eventPublisher = applicationContext;
|
||||
if (mappingContext instanceof ApplicationEventPublisherAware) {
|
||||
((ApplicationEventPublisherAware) mappingContext).setApplicationEventPublisher(eventPublisher);
|
||||
@@ -260,6 +256,30 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware {
|
||||
resourceLoader = applicationContext;
|
||||
}
|
||||
|
||||
/**
|
||||
* Inspects the given {@link ApplicationContext} for {@link MongoPersistentEntityIndexCreator} and those in turn if
|
||||
* they were registered for the current {@link MappingContext}. If no creator for the current {@link MappingContext}
|
||||
* can be found we manually add the internally created one as {@link ApplicationListener} to make sure indexes get
|
||||
* created appropriately for entity types persisted through this {@link MongoTemplate} instance.
|
||||
*
|
||||
* @param context must not be {@literal null}.
|
||||
*/
|
||||
private void prepareIndexCreator(ApplicationContext context) {
|
||||
|
||||
String[] indexCreators = context.getBeanNamesForType(MongoPersistentEntityIndexCreator.class);
|
||||
|
||||
for (String creator : indexCreators) {
|
||||
MongoPersistentEntityIndexCreator creatorBean = context.getBean(creator, MongoPersistentEntityIndexCreator.class);
|
||||
if (creatorBean.isIndexCreatorFor(mappingContext)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (context instanceof ConfigurableApplicationContext) {
|
||||
((ConfigurableApplicationContext) context).addApplicationListener(indexCreator);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the default {@link org.springframework.data.mongodb.core.core.convert.MongoConverter}.
|
||||
*
|
||||
@@ -337,7 +357,7 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware {
|
||||
|
||||
if (LOGGER.isDebugEnabled()) {
|
||||
LOGGER.debug(String.format("Executing query: %s sort: %s fields: %s in collection: $s",
|
||||
SerializationUtils.serializeToJsonSafely(queryObject), sortObject, fieldsObject, collectionName));
|
||||
serializeToJsonSafely(queryObject), sortObject, fieldsObject, collectionName));
|
||||
}
|
||||
|
||||
this.executeQueryInternal(new FindCallback(queryObject, fieldsObject), preparer, dch, collectionName);
|
||||
@@ -456,7 +476,7 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware {
|
||||
} else {
|
||||
query.limit(1);
|
||||
List<T> results = find(query, entityClass, collectionName);
|
||||
return (results.isEmpty() ? null : results.get(0));
|
||||
return results.isEmpty() ? null : results.get(0);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -467,19 +487,23 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware {
|
||||
}
|
||||
|
||||
public <T> List<T> find(final Query query, Class<T> entityClass, String collectionName) {
|
||||
CursorPreparer cursorPreparer = query == null ? null : new QueryCursorPreparer(query);
|
||||
return doFind(collectionName, query.getQueryObject(), query.getFieldsObject(), entityClass, cursorPreparer);
|
||||
|
||||
if (query == null) {
|
||||
return findAll(entityClass, collectionName);
|
||||
}
|
||||
|
||||
return doFind(collectionName, query.getQueryObject(), query.getFieldsObject(), entityClass,
|
||||
new QueryCursorPreparer(query));
|
||||
}
|
||||
|
||||
public <T> T findById(Object id, Class<T> entityClass) {
|
||||
MongoPersistentEntity<?> persistentEntity = mappingContext.getPersistentEntity(entityClass);
|
||||
return findById(id, entityClass, persistentEntity.getCollection());
|
||||
return findById(id, entityClass, determineCollectionName(entityClass));
|
||||
}
|
||||
|
||||
public <T> T findById(Object id, Class<T> entityClass, String collectionName) {
|
||||
MongoPersistentEntity<?> persistentEntity = mappingContext.getPersistentEntity(entityClass);
|
||||
MongoPersistentProperty idProperty = persistentEntity.getIdProperty();
|
||||
String idKey = idProperty == null ? ID : idProperty.getName();
|
||||
MongoPersistentProperty idProperty = persistentEntity == null ? null : persistentEntity.getIdProperty();
|
||||
String idKey = idProperty == null ? ID_FIELD : idProperty.getName();
|
||||
return doFindOne(collectionName, new BasicDBObject(idKey, id), null, entityClass);
|
||||
}
|
||||
|
||||
@@ -624,6 +648,8 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware {
|
||||
|
||||
assertUpdateableIdIfNotSet(objectToSave);
|
||||
|
||||
initializeVersionProperty(objectToSave);
|
||||
|
||||
BasicDBObject dbDoc = new BasicDBObject();
|
||||
|
||||
maybeEmitEvent(new BeforeConvertEvent<T>(objectToSave));
|
||||
@@ -636,6 +662,16 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware {
|
||||
maybeEmitEvent(new AfterSaveEvent<T>(objectToSave, dbDoc));
|
||||
}
|
||||
|
||||
private void initializeVersionProperty(Object entity) {
|
||||
|
||||
MongoPersistentEntity<?> mongoPersistentEntity = getPersistentEntity(entity.getClass());
|
||||
|
||||
if (mongoPersistentEntity == null || mongoPersistentEntity.hasVersionProperty()) {
|
||||
BeanWrapper<PersistentEntity<Object, ?>, Object> wrapper = BeanWrapper.create(entity, null);
|
||||
wrapper.setProperty(mongoPersistentEntity.getVersionProperty(), 0);
|
||||
}
|
||||
}
|
||||
|
||||
public void insert(Collection<? extends Object> batchToSave, Class<?> entityClass) {
|
||||
doInsertBatch(determineCollectionName(entityClass), batchToSave, this.mongoConverter);
|
||||
}
|
||||
@@ -680,6 +716,8 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware {
|
||||
|
||||
List<DBObject> dbObjectList = new ArrayList<DBObject>();
|
||||
for (T o : batchToSave) {
|
||||
|
||||
initializeVersionProperty(o);
|
||||
BasicDBObject dbDoc = new BasicDBObject();
|
||||
|
||||
maybeEmitEvent(new BeforeConvertEvent<T>(o));
|
||||
@@ -700,21 +738,83 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware {
|
||||
}
|
||||
|
||||
public void save(Object objectToSave) {
|
||||
|
||||
Assert.notNull(objectToSave);
|
||||
save(objectToSave, determineEntityCollectionName(objectToSave));
|
||||
}
|
||||
|
||||
public void save(Object objectToSave, String collectionName) {
|
||||
doSave(collectionName, objectToSave, this.mongoConverter);
|
||||
|
||||
Assert.notNull(objectToSave);
|
||||
Assert.hasText(collectionName);
|
||||
|
||||
MongoPersistentEntity<?> mongoPersistentEntity = getPersistentEntity(objectToSave.getClass());
|
||||
|
||||
// No optimistic locking -> simple save
|
||||
if (mongoPersistentEntity == null || !mongoPersistentEntity.hasVersionProperty()) {
|
||||
doSave(collectionName, objectToSave, this.mongoConverter);
|
||||
return;
|
||||
}
|
||||
|
||||
doSaveVersioned(objectToSave, mongoPersistentEntity, collectionName);
|
||||
}
|
||||
|
||||
private <T> void doSaveVersioned(T objectToSave, MongoPersistentEntity<?> entity, String collectionName) {
|
||||
|
||||
BeanWrapper<PersistentEntity<T, ?>, T> beanWrapper = BeanWrapper.create(objectToSave,
|
||||
this.mongoConverter.getConversionService());
|
||||
MongoPersistentProperty idProperty = entity.getIdProperty();
|
||||
MongoPersistentProperty versionProperty = entity.getVersionProperty();
|
||||
|
||||
Number version = beanWrapper.getProperty(versionProperty, Number.class, !versionProperty.usePropertyAccess());
|
||||
|
||||
// Fresh instance -> initialize version property
|
||||
if (version == null) {
|
||||
beanWrapper.setProperty(versionProperty, 0);
|
||||
doSave(collectionName, objectToSave, this.mongoConverter);
|
||||
} else {
|
||||
|
||||
assertUpdateableIdIfNotSet(objectToSave);
|
||||
|
||||
// Create query for entity with the id and old version
|
||||
Object id = beanWrapper.getProperty(idProperty);
|
||||
Query query = new Query(Criteria.where(idProperty.getName()).is(id).and(versionProperty.getName()).is(version));
|
||||
|
||||
// Bump version number
|
||||
Number number = beanWrapper.getProperty(versionProperty, Number.class, false);
|
||||
beanWrapper.setProperty(versionProperty, number.longValue() + 1);
|
||||
|
||||
BasicDBObject dbObject = new BasicDBObject();
|
||||
|
||||
maybeEmitEvent(new BeforeConvertEvent<T>(objectToSave));
|
||||
this.mongoConverter.write(objectToSave, dbObject);
|
||||
|
||||
maybeEmitEvent(new BeforeSaveEvent<T>(objectToSave, dbObject));
|
||||
Update update = Update.fromDBObject(dbObject, ID_FIELD);
|
||||
|
||||
updateFirst(query, update, objectToSave.getClass());
|
||||
maybeEmitEvent(new AfterSaveEvent<T>(objectToSave, dbObject));
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
protected <T> void doSave(String collectionName, T objectToSave, MongoWriter<T> writer) {
|
||||
|
||||
assertUpdateableIdIfNotSet(objectToSave);
|
||||
|
||||
BasicDBObject dbDoc = new BasicDBObject();
|
||||
DBObject dbDoc = new BasicDBObject();
|
||||
|
||||
maybeEmitEvent(new BeforeConvertEvent<T>(objectToSave));
|
||||
writer.write(objectToSave, dbDoc);
|
||||
|
||||
if (!(objectToSave instanceof String)) {
|
||||
writer.write(objectToSave, dbDoc);
|
||||
} else {
|
||||
try {
|
||||
objectToSave = (T) JSON.parse((String) objectToSave);
|
||||
} catch (JSONParseException e) {
|
||||
throw new MappingException("Could not parse given String to save into a JSON document!", e);
|
||||
}
|
||||
}
|
||||
|
||||
maybeEmitEvent(new BeforeSaveEvent<T>(objectToSave, dbDoc));
|
||||
Object id = saveDBObject(collectionName, dbDoc, objectToSave.getClass());
|
||||
@@ -725,21 +825,17 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware {
|
||||
|
||||
protected Object insertDBObject(final String collectionName, final DBObject dbDoc, final Class<?> entityClass) {
|
||||
if (LOGGER.isDebugEnabled()) {
|
||||
LOGGER.debug("insert DBObject containing fields: " + dbDoc.keySet() + " in collection: " + collectionName);
|
||||
LOGGER.debug("Inserting DBObject containing fields: " + dbDoc.keySet() + " in collection: " + collectionName);
|
||||
}
|
||||
return execute(collectionName, new CollectionCallback<Object>() {
|
||||
public Object doInCollection(DBCollection collection) throws MongoException, DataAccessException {
|
||||
MongoAction mongoAction = new MongoAction(writeConcern, MongoActionOperation.INSERT, collectionName,
|
||||
entityClass, dbDoc, null);
|
||||
WriteConcern writeConcernToUse = prepareWriteConcern(mongoAction);
|
||||
WriteResult wr;
|
||||
if (writeConcernToUse == null) {
|
||||
wr = collection.insert(dbDoc);
|
||||
} else {
|
||||
wr = collection.insert(dbDoc, writeConcernToUse);
|
||||
}
|
||||
handleAnyWriteResultErrors(wr, dbDoc, "insert");
|
||||
return dbDoc.get(ID);
|
||||
WriteResult writeResult = writeConcernToUse == null ? collection.insert(dbDoc) : collection.insert(dbDoc,
|
||||
writeConcernToUse);
|
||||
handleAnyWriteResultErrors(writeResult, dbDoc, MongoActionOperation.INSERT);
|
||||
return dbDoc.get(ID_FIELD);
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -750,27 +846,23 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware {
|
||||
}
|
||||
|
||||
if (LOGGER.isDebugEnabled()) {
|
||||
LOGGER.debug("insert list of DBObjects containing " + dbDocList.size() + " items");
|
||||
LOGGER.debug("Inserting list of DBObjects containing " + dbDocList.size() + " items");
|
||||
}
|
||||
execute(collectionName, new CollectionCallback<Void>() {
|
||||
public Void doInCollection(DBCollection collection) throws MongoException, DataAccessException {
|
||||
MongoAction mongoAction = new MongoAction(writeConcern, MongoActionOperation.INSERT_LIST, collectionName, null,
|
||||
null, null);
|
||||
WriteConcern writeConcernToUse = prepareWriteConcern(mongoAction);
|
||||
WriteResult wr;
|
||||
if (writeConcernToUse == null) {
|
||||
wr = collection.insert(dbDocList);
|
||||
} else {
|
||||
wr = collection.insert(dbDocList.toArray((DBObject[]) new BasicDBObject[dbDocList.size()]), writeConcernToUse);
|
||||
}
|
||||
handleAnyWriteResultErrors(wr, null, "insert_list");
|
||||
WriteResult writeResult = writeConcernToUse == null ? collection.insert(dbDocList) : collection.insert(
|
||||
dbDocList.toArray((DBObject[]) new BasicDBObject[dbDocList.size()]), writeConcernToUse);
|
||||
handleAnyWriteResultErrors(writeResult, null, MongoActionOperation.INSERT_LIST);
|
||||
return null;
|
||||
}
|
||||
});
|
||||
|
||||
List<ObjectId> ids = new ArrayList<ObjectId>();
|
||||
for (DBObject dbo : dbDocList) {
|
||||
Object id = dbo.get(ID);
|
||||
Object id = dbo.get(ID_FIELD);
|
||||
if (id instanceof ObjectId) {
|
||||
ids.add((ObjectId) id);
|
||||
} else {
|
||||
@@ -783,21 +875,17 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware {
|
||||
|
||||
protected Object saveDBObject(final String collectionName, final DBObject dbDoc, final Class<?> entityClass) {
|
||||
if (LOGGER.isDebugEnabled()) {
|
||||
LOGGER.debug("save DBObject containing fields: " + dbDoc.keySet());
|
||||
LOGGER.debug("Saving DBObject containing fields: " + dbDoc.keySet());
|
||||
}
|
||||
return execute(collectionName, new CollectionCallback<Object>() {
|
||||
public Object doInCollection(DBCollection collection) throws MongoException, DataAccessException {
|
||||
MongoAction mongoAction = new MongoAction(writeConcern, MongoActionOperation.SAVE, collectionName, entityClass,
|
||||
dbDoc, null);
|
||||
WriteConcern writeConcernToUse = prepareWriteConcern(mongoAction);
|
||||
WriteResult wr;
|
||||
if (writeConcernToUse == null) {
|
||||
wr = collection.save(dbDoc);
|
||||
} else {
|
||||
wr = collection.save(dbDoc, writeConcernToUse);
|
||||
}
|
||||
handleAnyWriteResultErrors(wr, dbDoc, "save");
|
||||
return dbDoc.get(ID);
|
||||
WriteResult writeResult = writeConcernToUse == null ? collection.save(dbDoc) : collection.save(dbDoc,
|
||||
writeConcernToUse);
|
||||
handleAnyWriteResultErrors(writeResult, dbDoc, MongoActionOperation.SAVE);
|
||||
return dbDoc.get(ID_FIELD);
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -840,21 +928,25 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware {
|
||||
entity);
|
||||
|
||||
if (LOGGER.isDebugEnabled()) {
|
||||
LOGGER.debug("calling update using query: " + queryObj + " and update: " + updateObj + " in collection: "
|
||||
LOGGER.debug("Calling update using query: " + queryObj + " and update: " + updateObj + " in collection: "
|
||||
+ collectionName);
|
||||
}
|
||||
|
||||
WriteResult wr;
|
||||
MongoAction mongoAction = new MongoAction(writeConcern, MongoActionOperation.UPDATE, collectionName,
|
||||
entityClass, updateObj, queryObj);
|
||||
WriteConcern writeConcernToUse = prepareWriteConcern(mongoAction);
|
||||
if (writeConcernToUse == null) {
|
||||
wr = collection.update(queryObj, updateObj, upsert, multi);
|
||||
} else {
|
||||
wr = collection.update(queryObj, updateObj, upsert, multi, writeConcernToUse);
|
||||
WriteResult writeResult = writeConcernToUse == null ? collection.update(queryObj, updateObj, upsert, multi)
|
||||
: collection.update(queryObj, updateObj, upsert, multi, writeConcernToUse);
|
||||
|
||||
if (entity != null && entity.hasVersionProperty() && !multi) {
|
||||
if (writeResult.getN() == 0) {
|
||||
throw new OptimisticLockingFailureException("Optimistic lock exception on saving entity: "
|
||||
+ updateObj.toMap().toString());
|
||||
}
|
||||
}
|
||||
handleAnyWriteResultErrors(wr, queryObj, "update with '" + updateObj + "'");
|
||||
return wr;
|
||||
|
||||
handleAnyWriteResultErrors(writeResult, queryObj, MongoActionOperation.UPDATE);
|
||||
return writeResult;
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -876,12 +968,12 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware {
|
||||
return;
|
||||
}
|
||||
|
||||
remove(getIdQueryFor(object), collection);
|
||||
doRemove(collection, getIdQueryFor(object), object.getClass());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a {@link Query} for the given entity by its id.
|
||||
*
|
||||
*
|
||||
* @param object must not be {@literal null}.
|
||||
* @return
|
||||
*/
|
||||
@@ -890,7 +982,7 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware {
|
||||
Assert.notNull(object);
|
||||
|
||||
MongoPersistentEntity<?> entity = mappingContext.getPersistentEntity(object.getClass());
|
||||
MongoPersistentProperty idProp = entity.getIdProperty();
|
||||
MongoPersistentProperty idProp = entity == null ? null : entity.getIdProperty();
|
||||
|
||||
if (idProp == null) {
|
||||
throw new MappingException("No id property found for object of type " + entity.getType().getName());
|
||||
@@ -906,7 +998,7 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware {
|
||||
private void assertUpdateableIdIfNotSet(Object entity) {
|
||||
|
||||
MongoPersistentEntity<?> persistentEntity = mappingContext.getPersistentEntity(entity.getClass());
|
||||
MongoPersistentProperty idProperty = persistentEntity.getIdProperty();
|
||||
MongoPersistentProperty idProperty = persistentEntity == null ? null : persistentEntity.getIdProperty();
|
||||
|
||||
if (idProperty == null) {
|
||||
return;
|
||||
@@ -928,27 +1020,30 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware {
|
||||
}
|
||||
|
||||
protected <T> void doRemove(final String collectionName, final Query query, final Class<T> entityClass) {
|
||||
|
||||
if (query == null) {
|
||||
throw new InvalidDataAccessApiUsageException("Query passed in to remove can't be null");
|
||||
}
|
||||
|
||||
final DBObject queryObject = query.getQueryObject();
|
||||
final MongoPersistentEntity<?> entity = getPersistentEntity(entityClass);
|
||||
|
||||
execute(collectionName, new CollectionCallback<Void>() {
|
||||
public Void doInCollection(DBCollection collection) throws MongoException, DataAccessException {
|
||||
|
||||
DBObject dboq = mapper.getMappedObject(queryObject, entity);
|
||||
WriteResult wr = null;
|
||||
|
||||
MongoAction mongoAction = new MongoAction(writeConcern, MongoActionOperation.REMOVE, collectionName,
|
||||
entityClass, null, queryObject);
|
||||
WriteConcern writeConcernToUse = prepareWriteConcern(mongoAction);
|
||||
|
||||
if (LOGGER.isDebugEnabled()) {
|
||||
LOGGER.debug("remove using query: " + dboq + " in collection: " + collection.getName());
|
||||
LOGGER.debug("Remove using query: {} in collection: {}.", new Object[] { dboq, collection.getName() });
|
||||
}
|
||||
if (writeConcernToUse == null) {
|
||||
wr = collection.remove(dboq);
|
||||
} else {
|
||||
wr = collection.remove(dboq, writeConcernToUse);
|
||||
}
|
||||
handleAnyWriteResultErrors(wr, dboq, "remove");
|
||||
|
||||
WriteResult wr = writeConcernToUse == null ? collection.remove(dboq) : collection.remove(dboq,
|
||||
writeConcernToUse);
|
||||
handleAnyWriteResultErrors(wr, dboq, MongoActionOperation.REMOVE);
|
||||
return null;
|
||||
}
|
||||
});
|
||||
@@ -1005,8 +1100,7 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware {
|
||||
handleCommandError(commandResult, commandObject);
|
||||
|
||||
if (LOGGER.isDebugEnabled()) {
|
||||
LOGGER.debug(String.format("MapReduce command result = [%s]",
|
||||
SerializationUtils.serializeToJsonSafely(commandObject)));
|
||||
LOGGER.debug("MapReduce command result = [{}]", serializeToJsonSafely(commandObject));
|
||||
}
|
||||
|
||||
MapReduceOutput mapReduceOutput = new MapReduceOutput(inputCollection, commandObject, commandResult);
|
||||
@@ -1059,15 +1153,14 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware {
|
||||
DBObject commandObject = new BasicDBObject("group", dbo);
|
||||
|
||||
if (LOGGER.isDebugEnabled()) {
|
||||
LOGGER.debug(String.format("Executing Group with DBObject [%s]",
|
||||
SerializationUtils.serializeToJsonSafely(commandObject)));
|
||||
LOGGER.debug("Executing Group with DBObject [{}]", serializeToJsonSafely(commandObject));
|
||||
}
|
||||
|
||||
CommandResult commandResult = executeCommand(commandObject, getDb().getOptions());
|
||||
handleCommandError(commandResult, commandObject);
|
||||
|
||||
if (LOGGER.isDebugEnabled()) {
|
||||
LOGGER.debug("Group command result = [" + commandResult + "]");
|
||||
LOGGER.debug("Group command result = [{}]", commandResult);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@@ -1172,7 +1265,7 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware {
|
||||
|
||||
/**
|
||||
* Create the specified collection using the provided options
|
||||
*
|
||||
*
|
||||
* @param collectionName
|
||||
* @param collectionOptions
|
||||
* @return the collection that was created
|
||||
@@ -1183,7 +1276,7 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware {
|
||||
DBCollection coll = db.createCollection(collectionName, collectionOptions);
|
||||
// TODO: Emit a collection created event
|
||||
if (LOGGER.isDebugEnabled()) {
|
||||
LOGGER.debug("Created collection [" + coll.getFullName() + "]");
|
||||
LOGGER.debug("Created collection [{}]", coll.getFullName());
|
||||
}
|
||||
return coll;
|
||||
}
|
||||
@@ -1194,7 +1287,7 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware {
|
||||
* Map the results of an ad-hoc query on the default MongoDB collection to an object using the template's converter
|
||||
* <p/>
|
||||
* The query document is specified as a standard DBObject and so is the fields specification.
|
||||
*
|
||||
*
|
||||
* @param collectionName name of the collection to retrieve the objects from
|
||||
* @param query the query document that specifies the criteria used to find a record
|
||||
* @param fields the document that specifies the fields to be returned
|
||||
@@ -1211,15 +1304,11 @@ 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.
|
||||
* <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.
|
||||
* <p/>
|
||||
* The query document is specified as a standard DBObject and so is the fields specification.
|
||||
* <p/>
|
||||
* Can be overridden by subclasses.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* @param collectionName name of the collection to retrieve the objects from
|
||||
* @param query the query document that specifies the criteria used to find a record
|
||||
* @param fields the document that specifies the fields to be returned
|
||||
@@ -1236,20 +1325,22 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware {
|
||||
|
||||
protected <S, T> List<T> doFind(String collectionName, DBObject query, DBObject fields, Class<S> entityClass,
|
||||
CursorPreparer preparer, DbObjectCallback<T> objectCallback) {
|
||||
|
||||
MongoPersistentEntity<?> entity = mappingContext.getPersistentEntity(entityClass);
|
||||
|
||||
if (LOGGER.isDebugEnabled()) {
|
||||
LOGGER.debug("find using query: " + query + " fields: " + fields + " for class: " + entityClass
|
||||
+ " in collection: " + collectionName);
|
||||
LOGGER.debug(String.format("find using query: %s fields: %s for class: %s in collection: %s",
|
||||
serializeToJsonSafely(query), fields, entityClass, collectionName));
|
||||
}
|
||||
|
||||
return executeFindMultiInternal(new FindCallback(mapper.getMappedObject(query, entity), fields), preparer,
|
||||
objectCallback, collectionName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Map the results of an ad-hoc query on the default MongoDB collection to a List using the template's converter.
|
||||
* <p/>
|
||||
* The query document is specified as a standard DBObject and so is the fields specification.
|
||||
*
|
||||
* Map the results of an ad-hoc query on the default MongoDB collection to a List using the template's converter. The
|
||||
* query document is specified as a standard DBObject and so is the fields specification.
|
||||
*
|
||||
* @param collectionName name of the collection to retrieve the objects from
|
||||
* @param query the query document that specifies the criteria used to find a record
|
||||
* @param fields the document that specifies the fields to be returned
|
||||
@@ -1288,7 +1379,7 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware {
|
||||
* The first document that matches the query is returned and also removed from the collection in the database.
|
||||
* <p/>
|
||||
* The query document is specified as a standard DBObject and so is the fields specification.
|
||||
*
|
||||
*
|
||||
* @param collectionName name of the collection to retrieve the objects from
|
||||
* @param query the query document that specifies the criteria used to find a record
|
||||
* @param entityClass the parameterized type of the returned list.
|
||||
@@ -1335,7 +1426,7 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware {
|
||||
|
||||
/**
|
||||
* Populates the id property of the saved object, if it's not set already.
|
||||
*
|
||||
*
|
||||
* @param savedObject
|
||||
* @param id
|
||||
*/
|
||||
@@ -1345,6 +1436,12 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware {
|
||||
return;
|
||||
}
|
||||
|
||||
if (savedObject instanceof BasicDBObject) {
|
||||
DBObject dbObject = (DBObject) savedObject;
|
||||
dbObject.put(ID_FIELD, id);
|
||||
return;
|
||||
}
|
||||
|
||||
MongoPersistentProperty idProp = getIdPropertyFor(savedObject.getClass());
|
||||
|
||||
if (idProp == null) {
|
||||
@@ -1354,21 +1451,13 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware {
|
||||
ConversionService conversionService = mongoConverter.getConversionService();
|
||||
BeanWrapper<PersistentEntity<Object, ?>, Object> wrapper = BeanWrapper.create(savedObject, conversionService);
|
||||
|
||||
try {
|
||||
Object idValue = wrapper.getProperty(idProp, idProp.getType(), true);
|
||||
|
||||
Object idValue = wrapper.getProperty(idProp, idProp.getType(), true);
|
||||
|
||||
if (idValue != null) {
|
||||
return;
|
||||
}
|
||||
|
||||
wrapper.setProperty(idProp, id);
|
||||
|
||||
} catch (IllegalAccessException e) {
|
||||
throw new MappingException(e.getMessage(), e);
|
||||
} catch (InvocationTargetException e) {
|
||||
throw new MappingException(e.getMessage(), e);
|
||||
if (idValue != null) {
|
||||
return;
|
||||
}
|
||||
|
||||
wrapper.setProperty(idProp, id);
|
||||
}
|
||||
|
||||
private DBCollection getAndPrepareCollection(DB db, String collectionName) {
|
||||
@@ -1388,7 +1477,7 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware {
|
||||
* <li>Execute the given {@link ConnectionCallback} for a {@link DBObject}.</li>
|
||||
* <li>Apply the given {@link DbObjectCallback} to each of the {@link DBObject}s to obtain the result.</li>
|
||||
* <ol>
|
||||
*
|
||||
*
|
||||
* @param <T>
|
||||
* @param collectionCallback the callback to retrieve the {@link DBObject} with
|
||||
* @param objectCallback the {@link DbObjectCallback} to transform {@link DBObject}s into the actual domain type
|
||||
@@ -1429,19 +1518,32 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware {
|
||||
CursorPreparer preparer, DbObjectCallback<T> objectCallback, String collectionName) {
|
||||
|
||||
try {
|
||||
DBCursor cursor = collectionCallback.doInCollection(getAndPrepareCollection(getDb(), collectionName));
|
||||
|
||||
if (preparer != null) {
|
||||
cursor = preparer.prepare(cursor);
|
||||
DBCursor cursor = null;
|
||||
|
||||
try {
|
||||
|
||||
cursor = collectionCallback.doInCollection(getAndPrepareCollection(getDb(), collectionName));
|
||||
|
||||
if (preparer != null) {
|
||||
cursor = preparer.prepare(cursor);
|
||||
}
|
||||
|
||||
List<T> result = new ArrayList<T>();
|
||||
|
||||
while (cursor.hasNext()) {
|
||||
DBObject object = cursor.next();
|
||||
result.add(objectCallback.doWith(object));
|
||||
}
|
||||
|
||||
return result;
|
||||
|
||||
} finally {
|
||||
|
||||
if (cursor != null) {
|
||||
cursor.close();
|
||||
}
|
||||
}
|
||||
|
||||
List<T> result = new ArrayList<T>();
|
||||
|
||||
for (DBObject object : cursor) {
|
||||
result.add(objectCallback.doWith(object));
|
||||
}
|
||||
|
||||
return result;
|
||||
} catch (RuntimeException e) {
|
||||
throw potentiallyConvertRuntimeException(e);
|
||||
}
|
||||
@@ -1451,15 +1553,27 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware {
|
||||
DocumentCallbackHandler callbackHandler, String collectionName) {
|
||||
|
||||
try {
|
||||
DBCursor cursor = collectionCallback.doInCollection(getAndPrepareCollection(getDb(), collectionName));
|
||||
|
||||
if (preparer != null) {
|
||||
cursor = preparer.prepare(cursor);
|
||||
DBCursor cursor = null;
|
||||
|
||||
try {
|
||||
cursor = collectionCallback.doInCollection(getAndPrepareCollection(getDb(), collectionName));
|
||||
|
||||
if (preparer != null) {
|
||||
cursor = preparer.prepare(cursor);
|
||||
}
|
||||
|
||||
while (cursor.hasNext()) {
|
||||
DBObject dbobject = cursor.next();
|
||||
callbackHandler.processDocument(dbobject);
|
||||
}
|
||||
|
||||
} finally {
|
||||
if (cursor != null) {
|
||||
cursor.close();
|
||||
}
|
||||
}
|
||||
|
||||
for (DBObject dbobject : cursor) {
|
||||
callbackHandler.processDocument(dbobject);
|
||||
}
|
||||
} catch (RuntimeException e) {
|
||||
throw potentiallyConvertRuntimeException(e);
|
||||
}
|
||||
@@ -1470,7 +1584,8 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware {
|
||||
}
|
||||
|
||||
private MongoPersistentProperty getIdPropertyFor(Class<?> type) {
|
||||
return mappingContext.getPersistentEntity(type).getIdProperty();
|
||||
MongoPersistentEntity<?> persistentEntity = mappingContext.getPersistentEntity(type);
|
||||
return persistentEntity == null ? null : persistentEntity.getIdProperty();
|
||||
}
|
||||
|
||||
private <T> String determineEntityCollectionName(T obj) {
|
||||
@@ -1497,37 +1612,45 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware {
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks and handles any errors.
|
||||
* <p/>
|
||||
* Current implementation logs errors. Future version may make this configurable to log warning, errors or throw
|
||||
* exception.
|
||||
* Handles {@link WriteResult} errors based on the configured {@link WriteResultChecking}.
|
||||
*
|
||||
* @param writeResult
|
||||
* @param query
|
||||
* @param operation
|
||||
*/
|
||||
protected void handleAnyWriteResultErrors(WriteResult wr, DBObject query, String operation) {
|
||||
protected void handleAnyWriteResultErrors(WriteResult writeResult, DBObject query, MongoActionOperation operation) {
|
||||
|
||||
if (WriteResultChecking.NONE == this.writeResultChecking) {
|
||||
if (writeResultChecking == WriteResultChecking.NONE) {
|
||||
return;
|
||||
}
|
||||
|
||||
String error = wr.getError();
|
||||
String error = writeResult.getError();
|
||||
|
||||
if (error != null) {
|
||||
String message;
|
||||
if (operation.equals("insert") || operation.equals("save")) {
|
||||
// assuming the insert operations will begin with insert string
|
||||
if (error == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
String message;
|
||||
|
||||
switch (operation) {
|
||||
|
||||
case INSERT:
|
||||
case SAVE:
|
||||
message = String.format("Insert/Save for %s failed: %s", query, error);
|
||||
} else if (operation.equals("insert_list")) {
|
||||
break;
|
||||
case INSERT_LIST:
|
||||
message = String.format("Insert list failed: %s", error);
|
||||
} else {
|
||||
break;
|
||||
default:
|
||||
message = String.format("Execution of %s%s failed: %s", operation,
|
||||
query == null ? "" : "' using '" + query.toString() + "' query", error);
|
||||
}
|
||||
query == null ? "" : " using query " + query.toString(), error);
|
||||
}
|
||||
|
||||
if (WriteResultChecking.EXCEPTION == this.writeResultChecking) {
|
||||
throw new DataIntegrityViolationException(message);
|
||||
} else {
|
||||
LOGGER.error(message);
|
||||
return;
|
||||
}
|
||||
if (writeResultChecking == WriteResultChecking.EXCEPTION) {
|
||||
throw new DataIntegrityViolationException(message);
|
||||
} else {
|
||||
LOGGER.error(message);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1615,7 +1738,6 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware {
|
||||
private static class FindCallback implements CollectionCallback<DBCursor> {
|
||||
|
||||
private final DBObject query;
|
||||
|
||||
private final DBObject fields;
|
||||
|
||||
public FindCallback(DBObject query) {
|
||||
@@ -1723,12 +1845,13 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware {
|
||||
}
|
||||
}
|
||||
|
||||
private class DefaultWriteConcernResolver implements WriteConcernResolver {
|
||||
private enum DefaultWriteConcernResolver implements WriteConcernResolver {
|
||||
|
||||
INSTANCE;
|
||||
|
||||
public WriteConcern resolve(MongoAction action) {
|
||||
return action.getDefaultWriteConcern();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class QueryCursorPreparer implements CursorPreparer {
|
||||
@@ -1792,7 +1915,7 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware {
|
||||
* Creates a new {@link GeoNearResultDbObjectCallback} using the given {@link DbObjectCallback} delegate for
|
||||
* {@link GeoResult} content unmarshalling.
|
||||
*
|
||||
* @param delegate
|
||||
* @param delegate must not be {@literal null}.
|
||||
*/
|
||||
public GeoNearResultDbObjectCallback(DbObjectCallback<T> delegate, Metric metric) {
|
||||
Assert.notNull(delegate);
|
||||
|
||||
@@ -47,7 +47,7 @@ public class SimpleMongoDbFactory implements DisposableBean, MongoDbFactory {
|
||||
* Create an instance of {@link SimpleMongoDbFactory} given the {@link Mongo} instance and database name.
|
||||
*
|
||||
* @param mongo Mongo instance, must not be {@literal null}.
|
||||
* @param databaseName database name, not be {@literal null}.
|
||||
* @param databaseName database name, not be {@literal null} or empty.
|
||||
*/
|
||||
public SimpleMongoDbFactory(Mongo mongo, String databaseName) {
|
||||
this(mongo, databaseName, UserCredentials.NO_CREDENTIALS, false);
|
||||
@@ -57,7 +57,7 @@ public class SimpleMongoDbFactory implements DisposableBean, MongoDbFactory {
|
||||
* Create an instance of SimpleMongoDbFactory given the Mongo instance, database name, and username/password
|
||||
*
|
||||
* @param mongo Mongo instance, must not be {@literal null}.
|
||||
* @param databaseName Database name, must not be {@literal null}.
|
||||
* @param databaseName Database name, must not be {@literal null} or empty.
|
||||
* @param credentials username and password.
|
||||
*/
|
||||
public SimpleMongoDbFactory(Mongo mongo, String databaseName, UserCredentials credentials) {
|
||||
|
||||
@@ -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.
|
||||
@@ -13,27 +13,25 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.data.mongodb.core;
|
||||
|
||||
import com.mongodb.WriteConcern;
|
||||
|
||||
/**
|
||||
* A strategy interface to determine the WriteConcern to use for a given MongoDbAction.
|
||||
*
|
||||
* Return the passed in default WriteConcern (a property on MongoAction) if no determination can be made.
|
||||
* A strategy interface to determine the {@link WriteConcern} to use for a given {@link MongoAction}. Return the passed
|
||||
* in default {@link WriteConcern} (a property on {@link MongoAction}) if no determination can be made.
|
||||
*
|
||||
* @author Mark Pollack
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
public interface WriteConcernResolver {
|
||||
|
||||
/**
|
||||
* Resolve the WriteConcern given the MongoAction
|
||||
* Resolve the {@link WriteConcern} given the {@link MongoAction}.
|
||||
*
|
||||
* @param action describes the context of the Mongo action. Contains a default WriteConcern to use if one should not
|
||||
* be resolved.
|
||||
* @return a WriteConcern based on the passed in MongoAction value, maybe null
|
||||
* @param action describes the context of the Mongo action. Contains a default {@link WriteConcern} to use if one
|
||||
* should not be resolved.
|
||||
* @return a {@link WriteConcern} based on the passed in {@link MongoAction} value, maybe {@literal null}.
|
||||
*/
|
||||
WriteConcern resolve(MongoAction action);
|
||||
}
|
||||
|
||||
@@ -1,5 +1,28 @@
|
||||
/*
|
||||
* 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;
|
||||
|
||||
/**
|
||||
* Enum to represent how strict the check of {@link com.mongodb.WriteResult} shall be. It can either be skipped entirely
|
||||
* (use {@link #NONE}), or errors can be logged ({@link #LOG}) or cause an exception to be thrown {@link #EXCEPTION}.
|
||||
*
|
||||
* @author Thomas Risberg
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
public enum WriteResultChecking {
|
||||
|
||||
NONE, LOG, EXCEPTION
|
||||
}
|
||||
|
||||
@@ -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.convert;
|
||||
|
||||
import java.math.BigInteger;
|
||||
@@ -33,8 +32,8 @@ import org.springframework.data.mongodb.core.convert.MongoConverters.StringToObj
|
||||
* Base class for {@link MongoConverter} implementations. Sets up a {@link GenericConversionService} and populates basic
|
||||
* converters. Allows registering {@link CustomConversions}.
|
||||
*
|
||||
* @author Jon Brisbin <jbrisbin@vmware.com>
|
||||
* @author Oliver Gierke ogierke@vmware.com
|
||||
* @author Jon Brisbin
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
public abstract class AbstractMongoConverter implements MongoConverter, InitializingBean {
|
||||
|
||||
@@ -94,6 +93,14 @@ public abstract class AbstractMongoConverter implements MongoConverter, Initiali
|
||||
conversions.registerConvertersIn(conversionService);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.mongodb.core.convert.MongoWriter#convertToMongoType(java.lang.Object)
|
||||
*/
|
||||
public Object convertToMongoType(Object obj) {
|
||||
return convertToMongoType(obj, null);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.mongodb.core.core.convert.MongoConverter#getConversionService()
|
||||
|
||||
@@ -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,
|
||||
@@ -31,6 +31,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;
|
||||
@@ -93,6 +94,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) {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2011-2012 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.
|
||||
@@ -15,7 +15,6 @@
|
||||
*/
|
||||
package org.springframework.data.mongodb.core.convert;
|
||||
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
@@ -32,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;
|
||||
@@ -47,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;
|
||||
@@ -216,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) {
|
||||
@@ -253,13 +255,9 @@ public class MappingMongoConverter extends AbstractMongoConverter implements App
|
||||
public void doWithAssociation(Association<MongoPersistentProperty> association) {
|
||||
MongoPersistentProperty inverseProp = association.getInverse();
|
||||
Object obj = getValueInternal(inverseProp, dbo, evaluator, result);
|
||||
try {
|
||||
wrapper.setProperty(inverseProp, obj);
|
||||
} catch (IllegalAccessException e) {
|
||||
throw new MappingException(e.getMessage(), e);
|
||||
} catch (InvocationTargetException e) {
|
||||
throw new MappingException(e.getMessage(), e);
|
||||
}
|
||||
|
||||
wrapper.setProperty(inverseProp, obj);
|
||||
|
||||
}
|
||||
});
|
||||
|
||||
@@ -351,13 +349,14 @@ public class MappingMongoConverter extends AbstractMongoConverter implements App
|
||||
}
|
||||
|
||||
final BeanWrapper<MongoPersistentEntity<Object>, Object> wrapper = BeanWrapper.create(obj, conversionService);
|
||||
|
||||
// Write the ID
|
||||
final MongoPersistentProperty idProperty = entity.getIdProperty();
|
||||
|
||||
if (!dbo.containsField("_id") && null != idProperty) {
|
||||
|
||||
boolean fieldAccessOnly = idProperty.usePropertyAccess() ? false : useFieldAccessOnly;
|
||||
|
||||
try {
|
||||
Object id = wrapper.getProperty(idProperty, Object.class, useFieldAccessOnly);
|
||||
Object id = wrapper.getProperty(idProperty, Object.class, fieldAccessOnly);
|
||||
dbo.put("_id", idMapper.convertId(id));
|
||||
} catch (ConversionException ignored) {
|
||||
}
|
||||
@@ -371,7 +370,9 @@ public class MappingMongoConverter extends AbstractMongoConverter implements App
|
||||
return;
|
||||
}
|
||||
|
||||
Object propertyObj = wrapper.getProperty(prop, prop.getType(), useFieldAccessOnly);
|
||||
boolean fieldAccessOnly = prop.usePropertyAccess() ? false : useFieldAccessOnly;
|
||||
|
||||
Object propertyObj = wrapper.getProperty(prop, prop.getType(), fieldAccessOnly);
|
||||
|
||||
if (null != propertyObj) {
|
||||
if (!conversions.isSimpleType(propertyObj.getClass())) {
|
||||
@@ -676,6 +677,10 @@ public class MappingMongoConverter extends AbstractMongoConverter implements App
|
||||
|
||||
Assert.notNull(target);
|
||||
|
||||
if (target instanceof DBRef) {
|
||||
return (DBRef) target;
|
||||
}
|
||||
|
||||
MongoPersistentEntity<?> targetEntity = mappingContext.getPersistentEntity(target.getClass());
|
||||
|
||||
if (null == targetEntity) {
|
||||
@@ -720,11 +725,12 @@ public class MappingMongoConverter extends AbstractMongoConverter implements App
|
||||
|
||||
Assert.notNull(targetType);
|
||||
|
||||
Class<?> collectionType = targetType.getType();
|
||||
|
||||
if (sourceValue.isEmpty()) {
|
||||
return new HashSet<Object>();
|
||||
return getPotentiallyConvertedSimpleRead(new HashSet<Object>(), collectionType);
|
||||
}
|
||||
|
||||
Class<?> collectionType = targetType.getType();
|
||||
collectionType = Collection.class.isAssignableFrom(collectionType) ? collectionType : List.class;
|
||||
|
||||
Collection<Object> items = targetType.getType().isArray() ? new ArrayList<Object>() : CollectionFactory
|
||||
@@ -810,8 +816,12 @@ public class MappingMongoConverter extends AbstractMongoConverter implements App
|
||||
return rootList;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.mongodb.core.convert.MongoWriter#convertToMongoType(java.lang.Object, org.springframework.data.util.TypeInformation)
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public Object convertToMongoType(Object obj) {
|
||||
public Object convertToMongoType(Object obj, TypeInformation<?> typeInformation) {
|
||||
|
||||
if (obj == null) {
|
||||
return null;
|
||||
@@ -858,7 +868,12 @@ public class MappingMongoConverter extends AbstractMongoConverter implements App
|
||||
|
||||
DBObject newDbo = new BasicDBObject();
|
||||
this.write(obj, newDbo);
|
||||
return removeTypeInfoRecursively(newDbo);
|
||||
|
||||
if (typeInformation == null) {
|
||||
return removeTypeInfoRecursively(newDbo);
|
||||
}
|
||||
|
||||
return !obj.getClass().equals(typeInformation.getType()) ? newDbo : removeTypeInfoRecursively(newDbo);
|
||||
}
|
||||
|
||||
public BasicDBList maybeConvertList(Iterable<?> source) {
|
||||
@@ -930,7 +945,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();
|
||||
@@ -940,20 +954,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 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.
|
||||
@@ -17,6 +17,7 @@ package org.springframework.data.mongodb.core.convert;
|
||||
|
||||
import org.springframework.data.convert.EntityWriter;
|
||||
import org.springframework.data.mongodb.core.mapping.MongoPersistentProperty;
|
||||
import org.springframework.data.util.TypeInformation;
|
||||
|
||||
import com.mongodb.DBObject;
|
||||
import com.mongodb.DBRef;
|
||||
@@ -35,11 +36,21 @@ public interface MongoWriter<T> extends EntityWriter<T, DBObject> {
|
||||
* Converts the given object into one Mongo will be able to store natively. If the given object can already be stored
|
||||
* as is, no conversion will happen.
|
||||
*
|
||||
* @param obj
|
||||
* @param obj can be {@literal null}.
|
||||
* @return
|
||||
*/
|
||||
Object convertToMongoType(Object obj);
|
||||
|
||||
/**
|
||||
* Converts the given object into one Mongo will be able to store natively but retains the type information in case
|
||||
* the given {@link TypeInformation} differs from the given object type.
|
||||
*
|
||||
* @param obj can be {@literal null}.
|
||||
* @param typeInformation can be {@literal null}.
|
||||
* @return
|
||||
*/
|
||||
Object convertToMongoType(Object obj, TypeInformation<?> typeInformation);
|
||||
|
||||
/**
|
||||
* Creates a {@link DBRef} to refer to the given object.
|
||||
*
|
||||
|
||||
@@ -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,
|
||||
@@ -17,14 +17,16 @@ package org.springframework.data.mongodb.core.convert;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
import org.bson.types.BasicBSONList;
|
||||
import org.bson.types.ObjectId;
|
||||
import org.springframework.core.convert.ConversionException;
|
||||
import org.springframework.core.convert.ConversionService;
|
||||
import org.springframework.data.mapping.PersistentEntity;
|
||||
import org.springframework.data.mapping.PropertyPath;
|
||||
import org.springframework.data.mapping.PropertyReferenceException;
|
||||
import org.springframework.data.mapping.context.MappingContext;
|
||||
import org.springframework.data.mapping.context.PersistentPropertyPath;
|
||||
import org.springframework.data.mongodb.core.mapping.MongoPersistentEntity;
|
||||
import org.springframework.data.mongodb.core.mapping.MongoPersistentProperty;
|
||||
import org.springframework.util.Assert;
|
||||
@@ -32,11 +34,12 @@ import org.springframework.util.Assert;
|
||||
import com.mongodb.BasicDBList;
|
||||
import com.mongodb.BasicDBObject;
|
||||
import com.mongodb.DBObject;
|
||||
import com.mongodb.DBRef;
|
||||
|
||||
/**
|
||||
* A helper class to encapsulate any modifications of a Query object before it gets submitted to the database.
|
||||
*
|
||||
* @author Jon Brisbin <jbrisbin@vmware.com>
|
||||
* @author Jon Brisbin
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
public class QueryMapper {
|
||||
@@ -46,6 +49,7 @@ public class QueryMapper {
|
||||
|
||||
private final ConversionService conversionService;
|
||||
private final MongoConverter converter;
|
||||
private final MappingContext<? extends MongoPersistentEntity<?>, MongoPersistentProperty> mappingContext;
|
||||
|
||||
/**
|
||||
* Creates a new {@link QueryMapper} with the given {@link MongoConverter}.
|
||||
@@ -53,9 +57,12 @@ public class QueryMapper {
|
||||
* @param converter must not be {@literal null}.
|
||||
*/
|
||||
public QueryMapper(MongoConverter converter) {
|
||||
|
||||
Assert.notNull(converter);
|
||||
|
||||
this.conversionService = converter.getConversionService();
|
||||
this.converter = converter;
|
||||
this.mappingContext = converter.getMappingContext();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -68,47 +75,151 @@ public class QueryMapper {
|
||||
*/
|
||||
public DBObject getMappedObject(DBObject query, MongoPersistentEntity<?> entity) {
|
||||
|
||||
DBObject newDbo = new BasicDBObject();
|
||||
if (Keyword.isKeyword(query)) {
|
||||
return getMappedKeyword(new Keyword(query), entity);
|
||||
}
|
||||
|
||||
DBObject result = new BasicDBObject();
|
||||
|
||||
for (String key : query.keySet()) {
|
||||
|
||||
String newKey = key;
|
||||
MongoPersistentProperty targetProperty = getTargetProperty(key, entity);
|
||||
String newKey = determineKey(key, entity);
|
||||
Object value = query.get(key);
|
||||
|
||||
if (isIdKey(key, entity)) {
|
||||
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>();
|
||||
for (Object id : (Iterable<?>) valueDbo.get(inKey)) {
|
||||
ids.add(convertId(id));
|
||||
}
|
||||
valueDbo.put(inKey, ids.toArray(new Object[ids.size()]));
|
||||
} else {
|
||||
value = getMappedObject((DBObject) value, null);
|
||||
}
|
||||
} else {
|
||||
value = convertId(value);
|
||||
}
|
||||
newKey = "_id";
|
||||
} else if (key.matches(N_OR_PATTERN)) {
|
||||
// $or/$nor
|
||||
Iterable<?> conditions = (Iterable<?>) value;
|
||||
BasicBSONList newConditions = new BasicBSONList();
|
||||
Iterator<?> iter = conditions.iterator();
|
||||
while (iter.hasNext()) {
|
||||
newConditions.add(getMappedObject((DBObject) iter.next(), null));
|
||||
}
|
||||
value = newConditions;
|
||||
} else if (key.equals("$ne")) {
|
||||
value = convertId(value);
|
||||
}
|
||||
|
||||
newDbo.put(newKey, convertSimpleOrDBObject(value, null));
|
||||
result.put(newKey, getMappedValue(value, targetProperty, newKey));
|
||||
}
|
||||
|
||||
return newDbo;
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the given {@link DBObject} representing a keyword by mapping the keyword's value.
|
||||
*
|
||||
* @param query the {@link DBObject} representing a keyword (e.g. {@code $ne : … } )
|
||||
* @param entity
|
||||
* @return
|
||||
*/
|
||||
private DBObject getMappedKeyword(Keyword query, MongoPersistentEntity<?> entity) {
|
||||
|
||||
// $or/$nor
|
||||
if (query.key.matches(N_OR_PATTERN)) {
|
||||
|
||||
Iterable<?> conditions = (Iterable<?>) query.value;
|
||||
BasicDBList newConditions = new BasicDBList();
|
||||
|
||||
for (Object condition : conditions) {
|
||||
newConditions.add(getMappedObject((DBObject) condition, entity));
|
||||
}
|
||||
|
||||
return new BasicDBObject(query.key, newConditions);
|
||||
}
|
||||
|
||||
return new BasicDBObject(query.key, convertSimpleOrDBObject(query.value, entity));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the mapped keyword considered defining a criteria for the given property.
|
||||
*
|
||||
* @param keyword
|
||||
* @param property
|
||||
* @return
|
||||
*/
|
||||
public DBObject getMappedKeyword(Keyword keyword, MongoPersistentProperty property) {
|
||||
|
||||
if (property.isAssociation()) {
|
||||
convertAssociation(keyword.value, property);
|
||||
}
|
||||
|
||||
return new BasicDBObject(keyword.key, getMappedValue(keyword.value, property, keyword.key));
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 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) {
|
||||
|
||||
if (property == null) {
|
||||
return convertSimpleOrDBObject(source, null);
|
||||
}
|
||||
|
||||
if (property.isIdProperty() || "_id".equals(newKey)) {
|
||||
|
||||
if (source instanceof DBObject) {
|
||||
DBObject valueDbo = (DBObject) source;
|
||||
if (valueDbo.containsField("$in") || valueDbo.containsField("$nin")) {
|
||||
String inKey = valueDbo.containsField("$in") ? "$in" : "$nin";
|
||||
List<Object> ids = new ArrayList<Object>();
|
||||
for (Object id : (Iterable<?>) valueDbo.get(inKey)) {
|
||||
ids.add(convertId(id));
|
||||
}
|
||||
valueDbo.put(inKey, ids.toArray(new Object[ids.size()]));
|
||||
} else if (valueDbo.containsField("$ne")) {
|
||||
valueDbo.put("$ne", convertId(valueDbo.get("$ne")));
|
||||
} else {
|
||||
return getMappedObject((DBObject) source, null);
|
||||
}
|
||||
|
||||
return valueDbo;
|
||||
|
||||
} else {
|
||||
return convertId(source);
|
||||
}
|
||||
}
|
||||
|
||||
if (property.isAssociation()) {
|
||||
return Keyword.isKeyword(source) ? getMappedKeyword(new Keyword(source), property) : convertAssociation(source,
|
||||
property);
|
||||
}
|
||||
|
||||
return convertSimpleOrDBObject(source, mappingContext.getPersistentEntity(property));
|
||||
}
|
||||
|
||||
private MongoPersistentProperty getTargetProperty(String key, MongoPersistentEntity<?> entity) {
|
||||
|
||||
if (isIdKey(key, entity)) {
|
||||
return entity.getIdProperty();
|
||||
}
|
||||
|
||||
PersistentPropertyPath<MongoPersistentProperty> path = getPath(key, entity);
|
||||
return path == null ? null : path.getLeafProperty();
|
||||
}
|
||||
|
||||
private PersistentPropertyPath<MongoPersistentProperty> getPath(String key, MongoPersistentEntity<?> entity) {
|
||||
|
||||
if (entity == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
try {
|
||||
PropertyPath path = PropertyPath.from(key, entity.getTypeInformation());
|
||||
return mappingContext.getPersistentPropertyPath(path);
|
||||
} catch (PropertyReferenceException e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the translated key assuming the given one is a propert (path) reference.
|
||||
*
|
||||
* @param key the source key
|
||||
* @param entity the base entity
|
||||
* @return the translated key
|
||||
*/
|
||||
private String determineKey(String key, MongoPersistentEntity<?> entity) {
|
||||
|
||||
if (entity == null && DEFAULT_ID_NAMES.contains(key)) {
|
||||
return "_id";
|
||||
}
|
||||
|
||||
PersistentPropertyPath<MongoPersistentProperty> path = getPath(key, entity);
|
||||
return path == null ? key : path.toDotPath(MongoPersistentProperty.PropertyToFieldNameConverter.INSTANCE);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -131,6 +242,30 @@ public class QueryMapper {
|
||||
return converter.convertToMongoType(source);
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts the given source assuming it's actually an association to anoter object.
|
||||
*
|
||||
* @param source
|
||||
* @param property
|
||||
* @return
|
||||
*/
|
||||
private Object convertAssociation(Object source, MongoPersistentProperty property) {
|
||||
|
||||
if (property == null || !property.isAssociation()) {
|
||||
return source;
|
||||
}
|
||||
|
||||
if (source instanceof Iterable) {
|
||||
BasicDBList result = new BasicDBList();
|
||||
for (Object element : (Iterable<?>) source) {
|
||||
result.add(element instanceof DBRef ? element : converter.toDBRef(element, 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.
|
||||
*
|
||||
@@ -169,4 +304,44 @@ public class QueryMapper {
|
||||
|
||||
return converter.convertToMongoType(id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Value object to capture a query keyword representation.
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
private static class Keyword {
|
||||
|
||||
String key;
|
||||
Object value;
|
||||
|
||||
Keyword(Object source) {
|
||||
|
||||
Assert.isInstanceOf(DBObject.class, source);
|
||||
|
||||
DBObject value = (DBObject) source;
|
||||
|
||||
Assert.isTrue(value.keySet().size() == 1, "Keyword must have a single key only!");
|
||||
|
||||
this.key = value.keySet().iterator().next();
|
||||
this.value = value.get(key);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether the given value actually represents a keyword. If this returns {@literal true} it's safe to call
|
||||
* the constructor.
|
||||
*
|
||||
* @param value
|
||||
* @return
|
||||
*/
|
||||
static boolean isKeyword(Object value) {
|
||||
|
||||
if (!(value instanceof DBObject)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
DBObject dbObject = (DBObject) value;
|
||||
return dbObject.keySet().size() == 1 && dbObject.keySet().iterator().next().startsWith("$");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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,37 +13,51 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.data.mongodb.core.index;
|
||||
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.ApplicationEvent;
|
||||
import org.springframework.context.ApplicationEventPublisher;
|
||||
import org.springframework.data.mapping.event.MappingContextEvent;
|
||||
import org.springframework.data.mapping.context.MappingContextEvent;
|
||||
import org.springframework.data.mongodb.core.MongoTemplate;
|
||||
import org.springframework.data.mongodb.core.mapping.MongoPersistentEntity;
|
||||
import org.springframework.data.mongodb.core.mapping.MongoPersistentProperty;
|
||||
import org.springframework.data.mongodb.core.mapping.event.AfterLoadEvent;
|
||||
import org.springframework.data.mongodb.core.mapping.event.AfterSaveEvent;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
* An implementation of ApplicationEventPublisher that will only fire MappingContextEvents for use by the index creator
|
||||
* when MongoTemplate is used 'stand-alone', that is not declared inside a Spring ApplicationContext.
|
||||
* An implementation of ApplicationEventPublisher that will only fire {@link MappingContextEvent}s for use by the index
|
||||
* creator when MongoTemplate is used 'stand-alone', that is not declared inside a Spring {@link ApplicationContext}.
|
||||
* Declare {@link MongoTemplate} inside an {@link ApplicationContext} to enable the publishing of all persistence events
|
||||
* such as {@link AfterLoadEvent}, {@link AfterSaveEvent}, etc.
|
||||
*
|
||||
* Declare MongoTemplate inside an ApplicationContext to enable the publishing of all persistence events such as
|
||||
* {@link AfterLoadEvent}, {@link AfterSaveEvent}, etc.
|
||||
*
|
||||
* @author Jon Brisbin <jbrisbin@vmware.com>
|
||||
* @author Jon Brisbin
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
public class MongoMappingEventPublisher implements ApplicationEventPublisher {
|
||||
|
||||
private MongoPersistentEntityIndexCreator indexCreator;
|
||||
private final MongoPersistentEntityIndexCreator indexCreator;
|
||||
|
||||
/**
|
||||
* Creates a new {@link MongoMappingEventPublisher} for the given {@link MongoPersistentEntityIndexCreator}.
|
||||
*
|
||||
* @param indexCreator must not be {@literal null}.
|
||||
*/
|
||||
public MongoMappingEventPublisher(MongoPersistentEntityIndexCreator indexCreator) {
|
||||
|
||||
Assert.notNull(indexCreator);
|
||||
this.indexCreator = indexCreator;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.context.ApplicationEventPublisher#publishEvent(org.springframework.context.ApplicationEvent)
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public void publishEvent(ApplicationEvent event) {
|
||||
if (event instanceof MappingContextEvent) {
|
||||
indexCreator
|
||||
.onApplicationEvent((MappingContextEvent<MongoPersistentEntity<MongoPersistentProperty>, MongoPersistentProperty>) event);
|
||||
indexCreator.onApplicationEvent((MappingContextEvent<MongoPersistentEntity<?>, MongoPersistentProperty>) event);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,7 +24,8 @@ import org.slf4j.LoggerFactory;
|
||||
import org.springframework.context.ApplicationListener;
|
||||
import org.springframework.data.mapping.PersistentEntity;
|
||||
import org.springframework.data.mapping.PropertyHandler;
|
||||
import org.springframework.data.mapping.event.MappingContextEvent;
|
||||
import org.springframework.data.mapping.context.MappingContext;
|
||||
import org.springframework.data.mapping.context.MappingContextEvent;
|
||||
import org.springframework.data.mongodb.MongoDbFactory;
|
||||
import org.springframework.data.mongodb.core.mapping.MongoMappingContext;
|
||||
import org.springframework.data.mongodb.core.mapping.MongoPersistentEntity;
|
||||
@@ -44,25 +45,28 @@ import com.mongodb.util.JSON;
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
public class MongoPersistentEntityIndexCreator implements
|
||||
ApplicationListener<MappingContextEvent<MongoPersistentEntity<MongoPersistentProperty>, MongoPersistentProperty>> {
|
||||
ApplicationListener<MappingContextEvent<MongoPersistentEntity<?>, MongoPersistentProperty>> {
|
||||
|
||||
private static final Logger log = LoggerFactory.getLogger(MongoPersistentEntityIndexCreator.class);
|
||||
|
||||
private final Map<Class<?>, Boolean> classesSeen = new ConcurrentHashMap<Class<?>, Boolean>();
|
||||
private final MongoDbFactory mongoDbFactory;
|
||||
private final MongoMappingContext mappingContext;
|
||||
|
||||
/**
|
||||
* Creats a new {@link MongoPersistentEntityIndexCreator} for the given {@link MongoMappingContext} and
|
||||
* {@link MongoDbFactory}.
|
||||
*
|
||||
* @param mappingContext must not be {@@iteral null}
|
||||
* @param mongoDbFactory must not be {@@iteral null}
|
||||
* @param mappingContext must not be {@literal null}
|
||||
* @param mongoDbFactory must not be {@literal null}
|
||||
*/
|
||||
public MongoPersistentEntityIndexCreator(MongoMappingContext mappingContext, MongoDbFactory mongoDbFactory) {
|
||||
|
||||
Assert.notNull(mongoDbFactory);
|
||||
Assert.notNull(mappingContext);
|
||||
|
||||
this.mongoDbFactory = mongoDbFactory;
|
||||
this.mappingContext = mappingContext;
|
||||
|
||||
for (MongoPersistentEntity<?> entity : mappingContext.getPersistentEntities()) {
|
||||
checkForIndexes(entity);
|
||||
@@ -73,8 +77,11 @@ public class MongoPersistentEntityIndexCreator implements
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.context.ApplicationListener#onApplicationEvent(org.springframework.context.ApplicationEvent)
|
||||
*/
|
||||
public void onApplicationEvent(
|
||||
MappingContextEvent<MongoPersistentEntity<MongoPersistentProperty>, MongoPersistentProperty> event) {
|
||||
public void onApplicationEvent(MappingContextEvent<MongoPersistentEntity<?>, MongoPersistentProperty> event) {
|
||||
|
||||
if (!event.wasEmittedBy(mappingContext)) {
|
||||
return;
|
||||
}
|
||||
|
||||
PersistentEntity<?, ?> entity = event.getPersistentEntity();
|
||||
|
||||
@@ -163,6 +170,26 @@ public class MongoPersistentEntityIndexCreator implements
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether the current index creator was registered for the given {@link MappingContext}.
|
||||
*
|
||||
* @param context
|
||||
* @return
|
||||
*/
|
||||
public boolean isIndexCreatorFor(MappingContext<?, ?> context) {
|
||||
return this.mappingContext.equals(context);
|
||||
}
|
||||
|
||||
/**
|
||||
* Triggers the actual index creation.
|
||||
*
|
||||
* @param collection the collection to create the index in
|
||||
* @param name the name of the index about to be created
|
||||
* @param indexDefinition the index definition
|
||||
* @param unique whether it shall be a unique index
|
||||
* @param dropDups whether to drop duplicates
|
||||
* @param sparse sparse or not
|
||||
*/
|
||||
protected void ensureIndex(String collection, String name, DBObject indexDefinition, boolean unique,
|
||||
boolean dropDups, boolean sparse) {
|
||||
|
||||
|
||||
@@ -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,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 java.util.Comparator;
|
||||
@@ -23,7 +22,6 @@ import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.ApplicationContextAware;
|
||||
import org.springframework.context.expression.BeanFactoryAccessor;
|
||||
import org.springframework.context.expression.BeanFactoryResolver;
|
||||
import org.springframework.data.mapping.PersistentEntity;
|
||||
import org.springframework.data.mapping.model.BasicPersistentEntity;
|
||||
import org.springframework.data.mongodb.MongoCollectionUtils;
|
||||
import org.springframework.data.util.TypeInformation;
|
||||
@@ -34,10 +32,10 @@ import org.springframework.expression.spel.support.StandardEvaluationContext;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
/**
|
||||
* Mongo specific {@link PersistentEntity} implementation that adds Mongo specific meta-data such as the collection name
|
||||
* and the like.
|
||||
* MongoDB specific {@link MongoPersistentEntity} implementation that adds Mongo specific meta-data such as the
|
||||
* collection name and the like.
|
||||
*
|
||||
* @author Jon Brisbin <jbrisbin@vmware.com>
|
||||
* @author Jon Brisbin
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
public class BasicMongoPersistentEntity<T> extends BasicPersistentEntity<T, MongoPersistentProperty> implements
|
||||
@@ -76,18 +74,17 @@ public class BasicMongoPersistentEntity<T> extends BasicPersistentEntity<T, Mong
|
||||
* @see org.springframework.context.ApplicationContextAware#setApplicationContext(org.springframework.context.ApplicationContext)
|
||||
*/
|
||||
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
|
||||
|
||||
context.addPropertyAccessor(new BeanFactoryAccessor());
|
||||
context.setBeanResolver(new BeanFactoryResolver(applicationContext));
|
||||
context.setRootObject(applicationContext);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the collection the entity should be stored in.
|
||||
*
|
||||
* @return
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @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);
|
||||
}
|
||||
|
||||
@@ -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,
|
||||
@@ -27,14 +27,16 @@ import org.slf4j.LoggerFactory;
|
||||
import org.springframework.data.mapping.Association;
|
||||
import org.springframework.data.mapping.model.AnnotationBasedPersistentProperty;
|
||||
import org.springframework.data.mapping.model.SimpleTypeHolder;
|
||||
import org.springframework.util.ReflectionUtils;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
import com.mongodb.DBObject;
|
||||
|
||||
/**
|
||||
* Mongo specific {@link org.springframework.data.mapping.PersistentProperty} implementation.
|
||||
* MongoDB specific {@link org.springframework.data.mapping.MongoPersistentProperty} implementation.
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
* @author Patryk Wasik
|
||||
*/
|
||||
public class BasicMongoPersistentProperty extends AnnotationBasedPersistentProperty<MongoPersistentProperty> implements
|
||||
MongoPersistentProperty {
|
||||
@@ -45,6 +47,8 @@ public class BasicMongoPersistentProperty extends AnnotationBasedPersistentPrope
|
||||
private static final Set<Class<?>> SUPPORTED_ID_TYPES = new HashSet<Class<?>>();
|
||||
private static final Set<String> SUPPORTED_ID_PROPERTY_NAMES = new HashSet<String>();
|
||||
|
||||
private static final Field CAUSE_FIELD;
|
||||
|
||||
static {
|
||||
SUPPORTED_ID_TYPES.add(ObjectId.class);
|
||||
SUPPORTED_ID_TYPES.add(String.class);
|
||||
@@ -52,6 +56,8 @@ public class BasicMongoPersistentProperty extends AnnotationBasedPersistentPrope
|
||||
|
||||
SUPPORTED_ID_PROPERTY_NAMES.add("id");
|
||||
SUPPORTED_ID_PROPERTY_NAMES.add("_id");
|
||||
|
||||
CAUSE_FIELD = ReflectionUtils.findField(Throwable.class, "cause");
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -112,8 +118,9 @@ public class BasicMongoPersistentProperty extends AnnotationBasedPersistentPrope
|
||||
return annotation != null && StringUtils.hasText(annotation.value()) ? annotation.value() : field.getName();
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.springframework.data.mongodb.core.core.mapping.MongoPersistentProperty#getFieldOrder()
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.mongodb.core.mapping.MongoPersistentProperty#getFieldOrder()
|
||||
*/
|
||||
public int getFieldOrder() {
|
||||
org.springframework.data.mongodb.core.mapping.Field annotation = getField().getAnnotation(
|
||||
@@ -121,25 +128,36 @@ public class BasicMongoPersistentProperty extends AnnotationBasedPersistentPrope
|
||||
return annotation != null ? annotation.order() : Integer.MAX_VALUE;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.springframework.data.mapping.AbstractPersistentProperty#createAssociation()
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.mapping.model.AbstractPersistentProperty#createAssociation()
|
||||
*/
|
||||
@Override
|
||||
protected Association<MongoPersistentProperty> createAssociation() {
|
||||
return new Association<MongoPersistentProperty>(this, null);
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.springframework.data.mongodb.core.core.mapping.MongoPersistentProperty#isDbReference()
|
||||
*/
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.mongodb.core.mapping.MongoPersistentProperty#isDbReference()
|
||||
*/
|
||||
public boolean isDbReference() {
|
||||
return getField().isAnnotationPresent(DBRef.class);
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.springframework.data.mongodb.core.core.mapping.MongoPersistentProperty#getDBRef()
|
||||
*/
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.mongodb.core.mapping.MongoPersistentProperty#getDBRef()
|
||||
*/
|
||||
public DBRef getDBRef() {
|
||||
return getField().getAnnotation(DBRef.class);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.mongodb.core.mapping.MongoPersistentProperty#usePropertyAccess()
|
||||
*/
|
||||
public boolean usePropertyAccess() {
|
||||
return CAUSE_FIELD.equals(getField());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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,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 java.beans.PropertyDescriptor;
|
||||
@@ -23,12 +22,16 @@ import org.springframework.beans.BeansException;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.ApplicationContextAware;
|
||||
import org.springframework.data.mapping.context.AbstractMappingContext;
|
||||
import org.springframework.data.mapping.context.MappingContext;
|
||||
import org.springframework.data.mapping.model.SimpleTypeHolder;
|
||||
import org.springframework.data.util.TypeInformation;
|
||||
|
||||
/**
|
||||
* @author Jon Brisbin <jbrisbin@vmware.com>
|
||||
* @author Oliver Gierke ogierke@vmware.com
|
||||
* Default implementation of a {@link MappingContext} for MongoDB using {@link BasicMongoPersistentEntity} and
|
||||
* {@link BasicMongoPersistentProperty} as primary abstractions.
|
||||
*
|
||||
* @author Jon Brisbin
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
public class MongoMappingContext extends AbstractMappingContext<BasicMongoPersistentEntity<?>, MongoPersistentProperty>
|
||||
implements ApplicationContextAware {
|
||||
@@ -42,6 +45,15 @@ public class MongoMappingContext extends AbstractMappingContext<BasicMongoPersis
|
||||
setSimpleTypeHolder(MongoSimpleTypes.HOLDER);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.mapping.context.AbstractMappingContext#shouldCreatePersistentEntityFor(org.springframework.data.util.TypeInformation)
|
||||
*/
|
||||
@Override
|
||||
protected boolean shouldCreatePersistentEntityFor(TypeInformation<?> type) {
|
||||
return !MongoSimpleTypes.HOLDER.isSimpleType(type.getType());
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.mapping.AbstractMappingContext#createPersistentProperty(java.lang.reflect.Field, java.beans.PropertyDescriptor, org.springframework.data.mapping.MutablePersistentEntity, org.springframework.data.mapping.SimpleTypeHolder)
|
||||
@@ -72,7 +84,10 @@ public class MongoMappingContext extends AbstractMappingContext<BasicMongoPersis
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.context.ApplicationContextAware#setApplicationContext(org.springframework.context.ApplicationContext)
|
||||
*/
|
||||
@Override
|
||||
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
|
||||
|
||||
this.context = applicationContext;
|
||||
super.setApplicationContext(applicationContext);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,12 +1,33 @@
|
||||
/*
|
||||
* 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
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.data.mongodb.core.mapping;
|
||||
|
||||
import org.springframework.data.mapping.PersistentEntity;
|
||||
|
||||
/**
|
||||
* MongoDB specific {@link PersistentEntity} abstraction.
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
public interface MongoPersistentEntity<T> extends PersistentEntity<T, MongoPersistentProperty> {
|
||||
|
||||
/**
|
||||
* Returns the collection the entity shall be persisted to.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
String getCollection();
|
||||
}
|
||||
|
||||
@@ -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,
|
||||
@@ -19,9 +19,10 @@ import org.springframework.core.convert.converter.Converter;
|
||||
import org.springframework.data.mapping.PersistentProperty;
|
||||
|
||||
/**
|
||||
* Mongo specific {@link org.springframework.data.mapping.PersistentProperty} implementation.
|
||||
* MongoDB specific {@link org.springframework.data.mapping.PersistentProperty} extension.
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
* @author Patryk Wasik
|
||||
*/
|
||||
public interface MongoPersistentProperty extends PersistentProperty<MongoPersistentProperty> {
|
||||
|
||||
@@ -72,4 +73,12 @@ public interface MongoPersistentProperty extends PersistentProperty<MongoPersist
|
||||
return source.getFieldName();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether property access shall be used for reading the property value. This means it will use the getter
|
||||
* instead of field access.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
boolean usePropertyAccess();
|
||||
}
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
/*
|
||||
* Copyright (c) 2011 by the original author(s).
|
||||
* Copyright 2012-2012 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* 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,
|
||||
@@ -29,22 +29,25 @@ import org.springframework.data.mongodb.MongoCollectionUtils;
|
||||
import org.springframework.data.util.TypeInformation;
|
||||
|
||||
/**
|
||||
*
|
||||
* @deprecated use {@link MongoMappingContext} instead.
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
@Deprecated
|
||||
public class SimpleMongoMappingContext extends
|
||||
AbstractMappingContext<SimpleMongoMappingContext.SimpleMongoPersistentEntity<?>, MongoPersistentProperty> {
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.springframework.data.mapping.BasicMappingContext#createPersistentEntity(org.springframework.data.util.TypeInformation)
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.mapping.context.AbstractMappingContext#createPersistentEntity(org.springframework.data.util.TypeInformation)
|
||||
*/
|
||||
@Override
|
||||
protected <T> SimpleMongoPersistentEntity<T> createPersistentEntity(TypeInformation<T> typeInformation) {
|
||||
return new SimpleMongoPersistentEntity<T>(typeInformation);
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.springframework.data.mapping.BasicMappingContext#createPersistentProperty(java.lang.reflect.Field, java.beans.PropertyDescriptor, org.springframework.data.util.TypeInformation, org.springframework.data.mapping.BasicPersistentEntity)
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.mapping.context.AbstractMappingContext#createPersistentProperty(java.lang.reflect.Field, java.beans.PropertyDescriptor, org.springframework.data.mapping.model.MutablePersistentEntity, org.springframework.data.mapping.model.SimpleTypeHolder)
|
||||
*/
|
||||
@Override
|
||||
protected SimplePersistentProperty createPersistentProperty(Field field, PropertyDescriptor descriptor,
|
||||
@@ -112,6 +115,21 @@ public class SimpleMongoMappingContext extends
|
||||
public DBRef getDBRef() {
|
||||
return null;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.springframework.data.mongodb.core.core.mapping.MongoPersistentProperty#isVersion()
|
||||
*/
|
||||
public boolean isVersionProperty() {
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.mongodb.core.mapping.MongoPersistentProperty#usePropertyAccess()
|
||||
*/
|
||||
public boolean usePropertyAccess() {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
static class SimpleMongoPersistentEntity<T> extends BasicPersistentEntity<T, MongoPersistentProperty> implements
|
||||
@@ -130,5 +148,20 @@ public class SimpleMongoMappingContext extends
|
||||
public String getCollection() {
|
||||
return MongoCollectionUtils.getPreferredCollectionName(getType());
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.springframework.data.mongodb.core.core.mapping.MongoPersistentEntity#getVersionProperty()
|
||||
*/
|
||||
public MongoPersistentProperty getVersionProperty() {
|
||||
return null;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.mongodb.core.mapping.MongoPersistentEntity#hasVersionProperty()
|
||||
*/
|
||||
public boolean hasVersionProperty() {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,39 @@
|
||||
/*
|
||||
* 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;
|
||||
|
||||
import static java.lang.annotation.ElementType.*;
|
||||
import static java.lang.annotation.RetentionPolicy.*;
|
||||
|
||||
import java.lang.annotation.Documented;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
/**
|
||||
* Demarcates a property to be used as version field to implement optimistic locking on entities.
|
||||
*
|
||||
* @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);
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -25,7 +25,6 @@ import java.util.List;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import org.bson.BSON;
|
||||
import org.bson.types.BasicBSONList;
|
||||
import org.springframework.data.mongodb.InvalidMongoDbApiUsageException;
|
||||
import org.springframework.data.mongodb.core.geo.Circle;
|
||||
import org.springframework.data.mongodb.core.geo.Point;
|
||||
@@ -33,6 +32,7 @@ import org.springframework.data.mongodb.core.geo.Shape;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.ObjectUtils;
|
||||
|
||||
import com.mongodb.BasicDBList;
|
||||
import com.mongodb.BasicDBObject;
|
||||
import com.mongodb.DBObject;
|
||||
|
||||
@@ -400,7 +400,7 @@ public class Criteria implements CriteriaDefinition {
|
||||
* @param criteria
|
||||
*/
|
||||
public Criteria orOperator(Criteria... criteria) {
|
||||
BasicBSONList bsonList = createCriteriaList(criteria);
|
||||
BasicDBList bsonList = createCriteriaList(criteria);
|
||||
criteriaChain.add(new Criteria("$or").is(bsonList));
|
||||
return this;
|
||||
}
|
||||
@@ -411,7 +411,7 @@ public class Criteria implements CriteriaDefinition {
|
||||
* @param criteria
|
||||
*/
|
||||
public Criteria norOperator(Criteria... criteria) {
|
||||
BasicBSONList bsonList = createCriteriaList(criteria);
|
||||
BasicDBList bsonList = createCriteriaList(criteria);
|
||||
criteriaChain.add(new Criteria("$nor").is(bsonList));
|
||||
return this;
|
||||
}
|
||||
@@ -422,7 +422,7 @@ public class Criteria implements CriteriaDefinition {
|
||||
* @param criteria
|
||||
*/
|
||||
public Criteria andOperator(Criteria... criteria) {
|
||||
BasicBSONList bsonList = createCriteriaList(criteria);
|
||||
BasicDBList bsonList = createCriteriaList(criteria);
|
||||
criteriaChain.add(new Criteria("$and").is(bsonList));
|
||||
return this;
|
||||
}
|
||||
@@ -478,8 +478,8 @@ public class Criteria implements CriteriaDefinition {
|
||||
return queryCriteria;
|
||||
}
|
||||
|
||||
private BasicBSONList createCriteriaList(Criteria[] criteria) {
|
||||
BasicBSONList bsonList = new BasicBSONList();
|
||||
private BasicDBList createCriteriaList(Criteria[] criteria) {
|
||||
BasicDBList bsonList = new BasicDBList();
|
||||
for (Criteria c : criteria) {
|
||||
bsonList.add(c.getCriteriaObject());
|
||||
}
|
||||
@@ -514,9 +514,28 @@ public class Criteria implements CriteriaDefinition {
|
||||
|
||||
Criteria that = (Criteria) obj;
|
||||
|
||||
boolean keyEqual = this.key == null ? that.key == null : this.key.equals(that.key);
|
||||
boolean criteriaEqual = this.criteria.equals(that.criteria);
|
||||
boolean valueEqual = isEqual(this.isValue, that.isValue);
|
||||
if (this.criteriaChain.size() != that.criteriaChain.size()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for (int i = 0; i < this.criteriaChain.size(); i++) {
|
||||
|
||||
Criteria left = this.criteriaChain.get(i);
|
||||
Criteria right = that.criteriaChain.get(i);
|
||||
|
||||
if (!simpleCriteriaEquals(left, right)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private boolean simpleCriteriaEquals(Criteria left, Criteria right) {
|
||||
|
||||
boolean keyEqual = left.key == null ? right.key == null : left.key.equals(right.key);
|
||||
boolean criteriaEqual = left.criteria.equals(right.criteria);
|
||||
boolean valueEqual = isEqual(left.isValue, right.isValue);
|
||||
|
||||
return keyEqual && criteriaEqual && valueEqual;
|
||||
}
|
||||
|
||||
@@ -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-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.
|
||||
@@ -15,24 +15,32 @@
|
||||
*/
|
||||
package org.springframework.data.mongodb.core.query;
|
||||
|
||||
import static org.springframework.data.mongodb.core.SerializationUtils.*;
|
||||
import static org.springframework.data.mongodb.core.query.SerializationUtils.*;
|
||||
import static org.springframework.util.ObjectUtils.*;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.data.domain.Pageable;
|
||||
import org.springframework.data.domain.Sort;
|
||||
import org.springframework.data.mongodb.InvalidMongoDbApiUsageException;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
import com.mongodb.BasicDBObject;
|
||||
import com.mongodb.DBObject;
|
||||
|
||||
/**
|
||||
* @author Thomas Risberg
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
public class Query {
|
||||
|
||||
private LinkedHashMap<String, Criteria> criteria = new LinkedHashMap<String, Criteria>();
|
||||
private Field fieldSpec;
|
||||
private Sort sort;
|
||||
private Sort coreSort;
|
||||
@SuppressWarnings("deprecation")
|
||||
private org.springframework.data.mongodb.core.query.Sort sort;
|
||||
private int skip;
|
||||
private int limit;
|
||||
private String hint;
|
||||
@@ -96,14 +104,61 @@ public class Query {
|
||||
return this;
|
||||
}
|
||||
|
||||
public Sort sort() {
|
||||
/**
|
||||
* Returns a {@link org.springframework.data.mongodb.core.query.Sort} instance to define ordering properties.
|
||||
*
|
||||
* @deprecated use {@link #with(Sort)} instead
|
||||
* @return
|
||||
*/
|
||||
@Deprecated
|
||||
public org.springframework.data.mongodb.core.query.Sort sort() {
|
||||
if (this.sort == null) {
|
||||
this.sort = new Sort();
|
||||
this.sort = new org.springframework.data.mongodb.core.query.Sort();
|
||||
}
|
||||
|
||||
return this.sort;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the given pagination information on the {@link Query} instance. Will transparently set {@code skip} and
|
||||
* {@code limit} as well as applying the {@link Sort} instance defined with the {@link Pageable}.
|
||||
*
|
||||
* @param pageable
|
||||
* @return
|
||||
*/
|
||||
public Query with(Pageable pageable) {
|
||||
|
||||
if (pageable == null) {
|
||||
return this;
|
||||
}
|
||||
|
||||
this.limit = pageable.getPageSize();
|
||||
this.skip = pageable.getOffset();
|
||||
|
||||
return with(pageable.getSort());
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a {@link Sort} to the {@link Query} instance.
|
||||
*
|
||||
* @param sort
|
||||
* @return
|
||||
*/
|
||||
public Query with(Sort sort) {
|
||||
|
||||
if (sort == null) {
|
||||
return this;
|
||||
}
|
||||
|
||||
if (this.coreSort == null) {
|
||||
this.coreSort = sort;
|
||||
} else {
|
||||
this.coreSort = this.coreSort.and(sort);
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public DBObject getQueryObject() {
|
||||
DBObject dbo = new BasicDBObject();
|
||||
for (String k : criteria.keySet()) {
|
||||
@@ -121,11 +176,26 @@ public class Query {
|
||||
return fieldSpec.getFieldsObject();
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
public DBObject getSortObject() {
|
||||
if (this.sort == null) {
|
||||
|
||||
if (this.coreSort == null && this.sort == null) {
|
||||
return null;
|
||||
}
|
||||
return this.sort.getSortObject();
|
||||
|
||||
DBObject dbo = new BasicDBObject();
|
||||
|
||||
if (this.coreSort != null) {
|
||||
for (org.springframework.data.domain.Sort.Order order : this.coreSort) {
|
||||
dbo.put(order.getProperty(), order.isAscending() ? 1 : -1);
|
||||
}
|
||||
}
|
||||
|
||||
if (this.sort != null) {
|
||||
dbo.putAll(this.sort.getSortObject());
|
||||
}
|
||||
|
||||
return dbo;
|
||||
}
|
||||
|
||||
public int getSkip() {
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.data.mongodb.core;
|
||||
package org.springframework.data.mongodb.core.query;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Iterator;
|
||||
@@ -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.
|
||||
@@ -21,6 +21,15 @@ import java.util.Map;
|
||||
import com.mongodb.BasicDBObject;
|
||||
import com.mongodb.DBObject;
|
||||
|
||||
/**
|
||||
* Helper class to define sorting criterias for a Query instance.
|
||||
*
|
||||
* @author Thomas Risberg
|
||||
* @author Oliver Gierke
|
||||
* @deprecated use {@link org.springframework.data.domain.Sort} instead. See
|
||||
* {@link Query#with(org.springframework.data.domain.Sort)}.
|
||||
*/
|
||||
@Deprecated
|
||||
public class Sort {
|
||||
|
||||
private Map<String, Order> fieldSpec = new LinkedHashMap<String, Order>();
|
||||
@@ -40,7 +49,7 @@ public class Sort {
|
||||
public DBObject getSortObject() {
|
||||
DBObject dbo = new BasicDBObject();
|
||||
for (String k : fieldSpec.keySet()) {
|
||||
dbo.put(k, (fieldSpec.get(k).equals(Order.ASCENDING) ? 1 : -1));
|
||||
dbo.put(k, fieldSpec.get(k).equals(Order.ASCENDING) ? 1 : -1);
|
||||
}
|
||||
return dbo;
|
||||
}
|
||||
|
||||
@@ -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.
|
||||
@@ -15,13 +15,23 @@
|
||||
*/
|
||||
package org.springframework.data.mongodb.core.query;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.dao.InvalidDataAccessApiUsageException;
|
||||
|
||||
import com.mongodb.BasicDBObject;
|
||||
import com.mongodb.DBObject;
|
||||
import org.springframework.dao.InvalidDataAccessApiUsageException;
|
||||
|
||||
/**
|
||||
* Class to easily construct MongoDB update clauses.
|
||||
*
|
||||
* @author Thomas Risberg
|
||||
* @author Mark Pollack
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
public class Update {
|
||||
|
||||
public enum Position {
|
||||
@@ -40,6 +50,31 @@ public class Update {
|
||||
return new Update().set(key, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an {@link Update} instance from the given {@link DBObject}. Allows to explicitly exlude fields from making
|
||||
* it into the created {@link Update} object.
|
||||
*
|
||||
* @param object the source {@link DBObject} to create the update from.
|
||||
* @param exclude the fields to exclude.
|
||||
* @return
|
||||
*/
|
||||
public static Update fromDBObject(DBObject object, String... exclude) {
|
||||
|
||||
Update update = new Update();
|
||||
List<String> excludeList = Arrays.asList(exclude);
|
||||
|
||||
for (String key : object.keySet()) {
|
||||
|
||||
if (excludeList.contains(key)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
update.set(key, object.get(key));
|
||||
}
|
||||
|
||||
return update;
|
||||
}
|
||||
|
||||
/**
|
||||
* Update using the $set update modifier
|
||||
*
|
||||
|
||||
@@ -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.
|
||||
@@ -19,6 +19,7 @@ import java.io.InputStream;
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.core.io.support.ResourcePatternResolver;
|
||||
import org.springframework.data.domain.Sort;
|
||||
import org.springframework.data.mongodb.core.query.Query;
|
||||
|
||||
import com.mongodb.DBObject;
|
||||
@@ -29,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 {
|
||||
|
||||
@@ -41,30 +43,65 @@ 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);
|
||||
|
||||
/**
|
||||
* Returns all files matching the given query.
|
||||
* 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.
|
||||
*
|
||||
* @see https://jira.mongodb.org/browse/JAVA-431
|
||||
* @param query
|
||||
* @return
|
||||
*/
|
||||
@@ -102,4 +139,4 @@ public interface GridFsOperations extends ResourcePatternResolver {
|
||||
* @see ResourcePatternResolver#getResources(String)
|
||||
*/
|
||||
GridFsResource[] getResources(String filenamePattern);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -17,6 +17,7 @@ package org.springframework.data.mongodb.repository.config;
|
||||
|
||||
import java.lang.annotation.Documented;
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Inherited;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
@@ -38,6 +39,7 @@ import org.springframework.data.repository.query.QueryLookupStrategy.Key;
|
||||
@Target(ElementType.TYPE)
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Documented
|
||||
@Inherited
|
||||
@Import(MongoRepositoriesRegistrar.class)
|
||||
public @interface EnableMongoRepositories {
|
||||
|
||||
|
||||
@@ -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.
|
||||
@@ -15,8 +15,6 @@
|
||||
*/
|
||||
package org.springframework.data.mongodb.repository.query;
|
||||
|
||||
import static org.springframework.data.mongodb.repository.query.QueryUtils.*;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.data.domain.PageImpl;
|
||||
@@ -119,7 +117,7 @@ public abstract class AbstractMongoQuery implements RepositoryQuery {
|
||||
|
||||
protected List<?> readCollection(Query query) {
|
||||
|
||||
MongoEntityInformation<?, ?> metadata = method.getEntityInformation();
|
||||
MongoEntityMetadata<?> metadata = method.getEntityInformation();
|
||||
|
||||
String collectionName = metadata.getCollectionName();
|
||||
return operations.find(query, metadata.getJavaType(), collectionName);
|
||||
@@ -145,12 +143,7 @@ public abstract class AbstractMongoQuery implements RepositoryQuery {
|
||||
*/
|
||||
@Override
|
||||
public Object execute(Query query) {
|
||||
|
||||
if (pageable != null) {
|
||||
query = applyPagination(query, pageable);
|
||||
}
|
||||
|
||||
return readCollection(query);
|
||||
return readCollection(query.with(pageable));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -182,11 +175,10 @@ public abstract class AbstractMongoQuery implements RepositoryQuery {
|
||||
@SuppressWarnings({ "rawtypes", "unchecked" })
|
||||
Object execute(Query query) {
|
||||
|
||||
MongoEntityInformation<?, ?> metadata = method.getEntityInformation();
|
||||
MongoEntityMetadata<?> metadata = method.getEntityInformation();
|
||||
long count = operations.count(query, metadata.getCollectionName());
|
||||
|
||||
List<?> result = operations.find(applyPagination(query, pageable), metadata.getJavaType(),
|
||||
metadata.getCollectionName());
|
||||
List<?> result = operations.find(query.with(pageable), metadata.getJavaType(), metadata.getCollectionName());
|
||||
|
||||
return new PageImpl(result, pageable, count);
|
||||
}
|
||||
@@ -206,8 +198,8 @@ public abstract class AbstractMongoQuery implements RepositoryQuery {
|
||||
@Override
|
||||
Object execute(Query query) {
|
||||
|
||||
MongoEntityInformation<?, ?> entityInformation = method.getEntityInformation();
|
||||
return operations.findOne(query, entityInformation.getJavaType());
|
||||
MongoEntityMetadata<?> metadata = method.getEntityInformation();
|
||||
return operations.findOne(query, metadata.getJavaType());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -244,8 +236,8 @@ public abstract class AbstractMongoQuery implements RepositoryQuery {
|
||||
*/
|
||||
Object execute(Query query, Query countQuery) {
|
||||
|
||||
MongoEntityInformation<?, ?> information = method.getEntityInformation();
|
||||
long count = operations.count(countQuery, information.getCollectionName());
|
||||
MongoEntityMetadata<?> metadata = method.getEntityInformation();
|
||||
long count = operations.count(countQuery, metadata.getCollectionName());
|
||||
|
||||
return new GeoPage<Object>(doExecuteQuery(query), accessor.getPageable(), count);
|
||||
}
|
||||
@@ -262,12 +254,11 @@ public abstract class AbstractMongoQuery implements RepositoryQuery {
|
||||
|
||||
Distance maxDistance = accessor.getMaxDistance();
|
||||
if (maxDistance != null) {
|
||||
nearQuery.maxDistance(maxDistance);
|
||||
nearQuery.maxDistance(maxDistance).in(maxDistance.getMetric());
|
||||
}
|
||||
|
||||
MongoEntityInformation<?, ?> entityInformation = method.getEntityInformation();
|
||||
return (GeoResults<Object>) operations.geoNear(nearQuery, entityInformation.getJavaType(),
|
||||
entityInformation.getCollectionName());
|
||||
MongoEntityMetadata<?> metadata = method.getEntityInformation();
|
||||
return (GeoResults<Object>) operations.geoNear(nearQuery, metadata.getJavaType(), metadata.getCollectionName());
|
||||
}
|
||||
|
||||
private boolean isListOfGeoResult() {
|
||||
|
||||
@@ -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,7 +15,11 @@
|
||||
*/
|
||||
package org.springframework.data.mongodb.repository.query;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.data.domain.Pageable;
|
||||
import org.springframework.data.domain.Sort;
|
||||
@@ -24,7 +28,11 @@ import org.springframework.data.mongodb.core.geo.Distance;
|
||||
import org.springframework.data.mongodb.core.geo.Point;
|
||||
import org.springframework.data.mongodb.core.mapping.MongoPersistentProperty;
|
||||
import org.springframework.data.repository.query.ParameterAccessor;
|
||||
import org.springframework.data.util.TypeInformation;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
|
||||
import com.mongodb.DBRef;
|
||||
|
||||
/**
|
||||
* Custom {@link ParameterAccessor} that uses a {@link MongoWriter} to serialize parameters into Mongo format.
|
||||
@@ -78,12 +86,12 @@ public class ConvertingParameterAccessor implements MongoParameterAccessor {
|
||||
return delegate.getSort();
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.springframework.data.repository.query.ParameterAccessor#getBindableParameter(int)
|
||||
*/
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.repository.query.ParameterAccessor#getBindableValue(int)
|
||||
*/
|
||||
public Object getBindableValue(int index) {
|
||||
|
||||
return getConvertedValue(delegate.getBindableValue(index));
|
||||
return getConvertedValue(delegate.getBindableValue(index), null);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -94,7 +102,8 @@ public class ConvertingParameterAccessor implements MongoParameterAccessor {
|
||||
return delegate.getMaxDistance();
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.mongodb.repository.MongoParameterAccessor#getGeoNearLocation()
|
||||
*/
|
||||
public Point getGeoNearLocation() {
|
||||
@@ -104,11 +113,12 @@ public class ConvertingParameterAccessor implements MongoParameterAccessor {
|
||||
/**
|
||||
* Converts the given value with the underlying {@link MongoWriter}.
|
||||
*
|
||||
* @param value
|
||||
* @param value can be {@literal null}.
|
||||
* @param typeInformation can be {@literal null}.
|
||||
* @return
|
||||
*/
|
||||
private Object getConvertedValue(Object value) {
|
||||
return writer.convertToMongoType(value);
|
||||
private Object getConvertedValue(Object value, TypeInformation<?> typeInformation) {
|
||||
return writer.convertToMongoType(value, typeInformation == null ? null : typeInformation.getActualType());
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -158,7 +168,28 @@ public class ConvertingParameterAccessor implements MongoParameterAccessor {
|
||||
* @see org.springframework.data.mongodb.repository.ConvertingParameterAccessor.PotentiallConvertingIterator#nextConverted()
|
||||
*/
|
||||
public Object nextConverted(MongoPersistentProperty property) {
|
||||
return property.isAssociation() ? writer.toDBRef(next(), property) : getConvertedValue(next());
|
||||
|
||||
Object next = next();
|
||||
|
||||
if (next == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (property.isAssociation()) {
|
||||
if (next.getClass().isArray() || next instanceof Iterable) {
|
||||
|
||||
List<DBRef> dbRefs = new ArrayList<DBRef>();
|
||||
for (Object element : asCollection(next)) {
|
||||
dbRefs.add(writer.toDBRef(element, property));
|
||||
}
|
||||
|
||||
return dbRefs;
|
||||
} else {
|
||||
return writer.toDBRef(next, property);
|
||||
}
|
||||
}
|
||||
|
||||
return getConvertedValue(next, property.getTypeInformation());
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -170,6 +201,33 @@ public class ConvertingParameterAccessor implements MongoParameterAccessor {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the given object as {@link Collection}. Will do a copy of it if it implements {@link Iterable} or is an
|
||||
* array. Will return an empty {@link Collection} in case {@literal null} is given. Will wrap all other types into a
|
||||
* single-element collction
|
||||
*
|
||||
* @param source
|
||||
* @return
|
||||
*/
|
||||
private static Collection<?> asCollection(Object source) {
|
||||
|
||||
if (source instanceof Iterable) {
|
||||
|
||||
List<Object> result = new ArrayList<Object>();
|
||||
for (Object element : (Iterable<?>) source) {
|
||||
result.add(element);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
if (source == null) {
|
||||
return Collections.emptySet();
|
||||
}
|
||||
|
||||
return source.getClass().isArray() ? CollectionUtils.arrayToList(source) : Collections.singleton(source);
|
||||
}
|
||||
|
||||
/**
|
||||
* Custom {@link Iterator} that adds a method to access elements in a converted manner.
|
||||
*
|
||||
|
||||
@@ -1,47 +0,0 @@
|
||||
/*
|
||||
* Copyright 2011 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* 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.query;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* Interface for components being able to provide {@link EntityInformationCreator} for a given {@link Class}.
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
public interface EntityInformationCreator {
|
||||
|
||||
/**
|
||||
* Returns a {@link MongoEntityInformation} for the given domain class.
|
||||
*
|
||||
* @param domainClass the domain class to create the {@link MongoEntityInformation} for, must not be {@literal null}.
|
||||
* @return
|
||||
*/
|
||||
<T, ID extends Serializable> MongoEntityInformation<T, ID> getEntityInformation(Class<T> domainClass);
|
||||
|
||||
/**
|
||||
* Returns a {@link MongoEntityInformation} for the given domain class and class to retrieve the collection to query
|
||||
* against from.
|
||||
*
|
||||
* @param domainClass the domain class to create the {@link MongoEntityInformation} for, must not be {@literal null}.
|
||||
* @param collectionClass the class to derive the collection from queries to retrieve the domain classes from shall be
|
||||
* ran against, must not be {@literal null}.
|
||||
* @return
|
||||
*/
|
||||
<T, ID extends Serializable> MongoEntityInformation<T, ID> getEntityInformation(Class<T> domainClass,
|
||||
Class<?> collectionClass);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
/*
|
||||
* 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.query;
|
||||
|
||||
import org.springframework.data.repository.core.EntityMetadata;
|
||||
|
||||
/**
|
||||
* Extension of {@link EntityMetadata} to additionally expose the collection name an entity shall be persisted to.
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
public interface MongoEntityMetadata<T> extends EntityMetadata<T> {
|
||||
|
||||
/**
|
||||
* Returns the name of the collection the entity shall be persisted to.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
String getCollectionName();
|
||||
}
|
||||
@@ -147,8 +147,7 @@ class MongoQueryCreator extends AbstractQueryCreator<Query, Criteria> {
|
||||
return null;
|
||||
}
|
||||
|
||||
Query query = new Query(criteria);
|
||||
QueryUtils.applySorting(query, sort);
|
||||
Query query = new Query(criteria).with(sort);
|
||||
|
||||
if (LOG.isDebugEnabled()) {
|
||||
LOG.debug("Created query " + query);
|
||||
@@ -228,7 +227,7 @@ class MongoQueryCreator extends AbstractQueryCreator<Query, Criteria> {
|
||||
case SIMPLE_PROPERTY:
|
||||
return criteria.is(parameters.nextConverted(property));
|
||||
case NEGATING_SIMPLE_PROPERTY:
|
||||
return criteria.not().is(parameters.nextConverted(property));
|
||||
return criteria.ne(parameters.nextConverted(property));
|
||||
}
|
||||
|
||||
throw new IllegalArgumentException("Unsupported keyword!");
|
||||
|
||||
@@ -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.
|
||||
@@ -20,9 +20,12 @@ import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.core.annotation.AnnotationUtils;
|
||||
import org.springframework.data.mapping.context.MappingContext;
|
||||
import org.springframework.data.mongodb.core.geo.GeoPage;
|
||||
import org.springframework.data.mongodb.core.geo.GeoResult;
|
||||
import org.springframework.data.mongodb.core.geo.GeoResults;
|
||||
import org.springframework.data.mongodb.core.mapping.MongoPersistentEntity;
|
||||
import org.springframework.data.mongodb.core.mapping.MongoPersistentProperty;
|
||||
import org.springframework.data.mongodb.repository.Query;
|
||||
import org.springframework.data.repository.core.RepositoryMetadata;
|
||||
import org.springframework.data.repository.query.Parameters;
|
||||
@@ -33,8 +36,7 @@ import org.springframework.util.Assert;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
/**
|
||||
* TODO - Extract methods for {@link #getAnnotatedQuery()} into superclass as it is currently copied from Spring Data
|
||||
* JPA
|
||||
* Mongo specific implementation of {@link QueryMethod}.
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
@@ -45,19 +47,24 @@ public class MongoQueryMethod extends QueryMethod {
|
||||
.asList(GeoResult.class, GeoResults.class, GeoPage.class);
|
||||
|
||||
private final Method method;
|
||||
private final MongoEntityInformation<?, ?> entityInformation;
|
||||
private final MappingContext<? extends MongoPersistentEntity<?>, MongoPersistentProperty> mappingContext;
|
||||
|
||||
private MongoEntityMetadata<?> metadata;
|
||||
|
||||
/**
|
||||
* Creates a new {@link MongoQueryMethod} from the given {@link Method}.
|
||||
*
|
||||
* @param method
|
||||
*/
|
||||
public MongoQueryMethod(Method method, RepositoryMetadata metadata, EntityInformationCreator entityInformationCreator) {
|
||||
public MongoQueryMethod(Method method, RepositoryMetadata metadata,
|
||||
MappingContext<? extends MongoPersistentEntity<?>, MongoPersistentProperty> mappingContext) {
|
||||
|
||||
super(method, metadata);
|
||||
Assert.notNull(entityInformationCreator, "DefaultEntityInformationCreator must not be null!");
|
||||
|
||||
Assert.notNull(mappingContext, "MappingContext must not be null!");
|
||||
|
||||
this.method = method;
|
||||
this.entityInformation = entityInformationCreator.getEntityInformation(metadata.getReturnedDomainClass(method),
|
||||
getDomainClass());
|
||||
this.mappingContext = mappingContext;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -101,14 +108,30 @@ public class MongoQueryMethod extends QueryMethod {
|
||||
return StringUtils.hasText(value) ? value : null;
|
||||
}
|
||||
|
||||
/*
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.repository.query.QueryMethod#getEntityInformation()
|
||||
*/
|
||||
@Override
|
||||
public MongoEntityInformation<?, ?> getEntityInformation() {
|
||||
@SuppressWarnings("unchecked")
|
||||
public MongoEntityMetadata<?> getEntityInformation() {
|
||||
|
||||
return entityInformation;
|
||||
if (metadata == null) {
|
||||
|
||||
Class<?> returnedObjectType = getReturnedObjectType();
|
||||
Class<?> domainClass = getDomainClass();
|
||||
|
||||
MongoPersistentEntity<?> returnedEntity = mappingContext.getPersistentEntity(getReturnedObjectType());
|
||||
MongoPersistentEntity<?> managedEntity = mappingContext.getPersistentEntity(domainClass);
|
||||
returnedEntity = returnedEntity == null ? managedEntity : returnedEntity;
|
||||
MongoPersistentEntity<?> collectionEntity = domainClass.isAssignableFrom(returnedObjectType) ? returnedEntity
|
||||
: managedEntity;
|
||||
|
||||
this.metadata = new SimpleMongoEntityMetadata<Object>((Class<Object>) returnedEntity.getType(),
|
||||
collectionEntity.getCollection());
|
||||
}
|
||||
|
||||
return this.metadata;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -121,12 +144,11 @@ public class MongoQueryMethod extends QueryMethod {
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether te query is a geoNear query.
|
||||
* Returns whether te query is a geo near query.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public boolean isGeoNearQuery() {
|
||||
|
||||
return isGeoNearQuery(this.method);
|
||||
}
|
||||
|
||||
|
||||
@@ -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.
|
||||
@@ -15,12 +15,13 @@
|
||||
*/
|
||||
package org.springframework.data.mongodb.repository.query;
|
||||
|
||||
import com.mongodb.DBCursor;
|
||||
import org.springframework.data.domain.Pageable;
|
||||
import org.springframework.data.domain.Sort;
|
||||
import org.springframework.data.domain.Sort.Order;
|
||||
import org.springframework.data.mongodb.core.query.Query;
|
||||
|
||||
import com.mongodb.DBCursor;
|
||||
|
||||
/**
|
||||
* Collection of utility methods to apply sorting and pagination to a {@link DBCursor}.
|
||||
*
|
||||
@@ -36,10 +37,12 @@ public abstract class QueryUtils {
|
||||
* Applies the given {@link Pageable} to the given {@link Query}. Will do nothing if {@link Pageable} is
|
||||
* {@literal null}.
|
||||
*
|
||||
* @param query
|
||||
* @deprecated use {@link Query#with(Pageable)}.
|
||||
* @param query must not be {@literal null}.
|
||||
* @param pageable
|
||||
* @return
|
||||
*/
|
||||
@Deprecated
|
||||
public static Query applyPagination(Query query, Pageable pageable) {
|
||||
|
||||
if (pageable == null) {
|
||||
@@ -49,16 +52,18 @@ public abstract class QueryUtils {
|
||||
query.limit(pageable.getPageSize());
|
||||
query.skip(pageable.getOffset());
|
||||
|
||||
return applySorting(query, pageable.getSort());
|
||||
return query.with(pageable.getSort());
|
||||
}
|
||||
|
||||
/**
|
||||
* Applies the given {@link Sort} to the {@link Query}. Will do nothing if {@link Sort} is {@literal null}.
|
||||
*
|
||||
* @param query
|
||||
* @deprecated use {@link Query#with(Pageable)}.
|
||||
* @param query must not be {@literal null}.
|
||||
* @param sort
|
||||
* @return
|
||||
*/
|
||||
@Deprecated
|
||||
public static Query applySorting(Query query, Sort sort) {
|
||||
|
||||
if (sort == null) {
|
||||
|
||||
@@ -0,0 +1,60 @@
|
||||
/*
|
||||
* 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.query;
|
||||
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
* Bean based implementation of {@link MongoEntityMetadata}.
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
class SimpleMongoEntityMetadata<T> implements MongoEntityMetadata<T> {
|
||||
|
||||
private final Class<T> type;
|
||||
private final String collectionName;
|
||||
|
||||
/**
|
||||
* Creates a new {@link SimpleMongoEntityMetadata} using the given type and collection name.
|
||||
*
|
||||
* @param type must not be {@literal null}.
|
||||
* @param collectionName must not be {@literal null} or empty.
|
||||
*/
|
||||
public SimpleMongoEntityMetadata(Class<T> type, String collectionName) {
|
||||
|
||||
Assert.notNull(type, "Type must not be null!");
|
||||
Assert.hasText(collectionName, "Collection name must not be null or empty!");
|
||||
|
||||
this.type = type;
|
||||
this.collectionName = collectionName;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.repository.core.EntityMetadata#getJavaType()
|
||||
*/
|
||||
public Class<T> getJavaType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.mongodb.repository.query.MongoEntityMetadata#getCollectionName()
|
||||
*/
|
||||
public String getCollectionName() {
|
||||
return collectionName;
|
||||
}
|
||||
}
|
||||
@@ -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.
|
||||
@@ -73,7 +73,7 @@ public class StringBasedMongoQuery extends AbstractMongoQuery {
|
||||
query = new BasicQuery(queryString);
|
||||
}
|
||||
|
||||
QueryUtils.applySorting(query, accessor.getSort());
|
||||
query.with(accessor.getSort());
|
||||
|
||||
if (LOG.isDebugEnabled()) {
|
||||
LOG.debug(String.format("Created query %s", query.getQueryObject()));
|
||||
|
||||
@@ -1,66 +0,0 @@
|
||||
/*
|
||||
* Copyright 2011 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.data.mongodb.repository.support;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
import org.springframework.data.mapping.context.MappingContext;
|
||||
import org.springframework.data.mongodb.core.mapping.MongoPersistentEntity;
|
||||
import org.springframework.data.mongodb.core.mapping.MongoPersistentProperty;
|
||||
import org.springframework.data.mongodb.repository.query.EntityInformationCreator;
|
||||
import org.springframework.data.mongodb.repository.query.MongoEntityInformation;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
* Simple {@link EntityInformationCreator} to to create {@link MongoEntityInformation} instances based on a
|
||||
* {@link MappingContext}.
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
public class DefaultEntityInformationCreator implements EntityInformationCreator {
|
||||
|
||||
private final MappingContext<? extends MongoPersistentEntity<?>, MongoPersistentProperty> mappingContext;
|
||||
|
||||
public DefaultEntityInformationCreator(
|
||||
MappingContext<? extends MongoPersistentEntity<?>, MongoPersistentProperty> mappingContext) {
|
||||
Assert.notNull(mappingContext);
|
||||
this.mappingContext = mappingContext;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.mongodb.repository.support.EntityInformationCreator#getEntityInformation(java.lang.Class)
|
||||
*/
|
||||
public <T, ID extends Serializable> MongoEntityInformation<T, ID> getEntityInformation(Class<T> domainClass) {
|
||||
return getEntityInformation(domainClass, null);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.mongodb.repository.support.EntityInformationCreator#getEntityInformation(java.lang.Class, java.lang.Class)
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public <T, ID extends Serializable> MongoEntityInformation<T, ID> getEntityInformation(Class<T> domainClass,
|
||||
Class<?> collectionClass) {
|
||||
|
||||
MongoPersistentEntity<T> persistentEntity = (MongoPersistentEntity<T>) mappingContext
|
||||
.getPersistentEntity(domainClass);
|
||||
String customCollectionName = collectionClass == null ? null : mappingContext.getPersistentEntity(collectionClass)
|
||||
.getCollection();
|
||||
|
||||
return new MappingMongoEntityInformation<T, ID>(persistentEntity, customCollectionName);
|
||||
}
|
||||
}
|
||||
@@ -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.
|
||||
@@ -25,7 +25,7 @@ import org.springframework.data.domain.Sort;
|
||||
import org.springframework.data.mongodb.core.MongoOperations;
|
||||
import org.springframework.data.mongodb.core.index.Index;
|
||||
import org.springframework.data.mongodb.core.query.Order;
|
||||
import org.springframework.data.mongodb.repository.query.MongoEntityInformation;
|
||||
import org.springframework.data.mongodb.repository.query.MongoEntityMetadata;
|
||||
import org.springframework.data.mongodb.repository.query.PartTreeMongoQuery;
|
||||
import org.springframework.data.mongodb.repository.query.QueryUtils;
|
||||
import org.springframework.data.repository.core.support.QueryCreationListener;
|
||||
@@ -85,7 +85,7 @@ class IndexEnsuringQueryCreationListener implements QueryCreationListener<PartTr
|
||||
}
|
||||
}
|
||||
|
||||
MongoEntityInformation<?, ?> metadata = query.getQueryMethod().getEntityInformation();
|
||||
MongoEntityMetadata<?> metadata = query.getQueryMethod().getEntityInformation();
|
||||
operations.indexOps(metadata.getCollectionName()).ensureIndex(index);
|
||||
LOG.debug(String.format("Created %s!", index));
|
||||
}
|
||||
@@ -99,4 +99,4 @@ class IndexEnsuringQueryCreationListener implements QueryCreationListener<PartTr
|
||||
org.springframework.data.domain.Sort.Order order = sort.getOrderFor(property);
|
||||
return order == null ? Order.DESCENDING : order.isAscending() ? Order.ASCENDING : Order.DESCENDING;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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.
|
||||
@@ -21,10 +21,11 @@ import java.io.Serializable;
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
import org.springframework.data.mapping.context.MappingContext;
|
||||
import org.springframework.data.mapping.model.MappingException;
|
||||
import org.springframework.data.mongodb.core.MongoOperations;
|
||||
import org.springframework.data.mongodb.core.MongoTemplate;
|
||||
import org.springframework.data.mongodb.core.mapping.MongoPersistentEntity;
|
||||
import org.springframework.data.mongodb.core.mapping.MongoPersistentProperty;
|
||||
import org.springframework.data.mongodb.repository.MongoRepository;
|
||||
import org.springframework.data.mongodb.repository.query.EntityInformationCreator;
|
||||
import org.springframework.data.mongodb.repository.query.MongoEntityInformation;
|
||||
import org.springframework.data.mongodb.repository.query.MongoQueryMethod;
|
||||
import org.springframework.data.mongodb.repository.query.PartTreeMongoQuery;
|
||||
@@ -46,20 +47,18 @@ import org.springframework.util.Assert;
|
||||
public class MongoRepositoryFactory extends RepositoryFactorySupport {
|
||||
|
||||
private final MongoOperations mongoOperations;
|
||||
private final EntityInformationCreator entityInformationCreator;
|
||||
private final MappingContext<? extends MongoPersistentEntity<?>, MongoPersistentProperty> mappingContext;
|
||||
|
||||
/**
|
||||
* Creates a new {@link MongoRepositoryFactory} with the given {@link MongoTemplate} and {@link MappingContext}.
|
||||
* Creates a new {@link MongoRepositoryFactory} with the given {@link MongoOperations}.
|
||||
*
|
||||
* @param template must not be {@literal null}
|
||||
* @param mappingContext
|
||||
* @param mongoOperations must not be {@literal null}
|
||||
*/
|
||||
public MongoRepositoryFactory(MongoOperations mongoOperations) {
|
||||
|
||||
Assert.notNull(mongoOperations);
|
||||
this.mongoOperations = mongoOperations;
|
||||
this.entityInformationCreator = new DefaultEntityInformationCreator(mongoOperations.getConverter()
|
||||
.getMappingContext());
|
||||
this.mappingContext = mongoOperations.getConverter().getMappingContext();
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -117,7 +116,7 @@ public class MongoRepositoryFactory extends RepositoryFactorySupport {
|
||||
*/
|
||||
public RepositoryQuery resolveQuery(Method method, RepositoryMetadata metadata, NamedQueries namedQueries) {
|
||||
|
||||
MongoQueryMethod queryMethod = new MongoQueryMethod(method, metadata, entityInformationCreator);
|
||||
MongoQueryMethod queryMethod = new MongoQueryMethod(method, metadata, mappingContext);
|
||||
String namedQueryName = queryMethod.getNamedQueryName();
|
||||
|
||||
if (namedQueries.hasQuery(namedQueryName)) {
|
||||
@@ -136,7 +135,16 @@ public class MongoRepositoryFactory extends RepositoryFactorySupport {
|
||||
* @see org.springframework.data.repository.core.support.RepositoryFactorySupport#getEntityInformation(java.lang.Class)
|
||||
*/
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public <T, ID extends Serializable> MongoEntityInformation<T, ID> getEntityInformation(Class<T> domainClass) {
|
||||
return entityInformationCreator.getEntityInformation(domainClass);
|
||||
|
||||
MongoPersistentEntity<?> entity = mappingContext.getPersistentEntity(domainClass);
|
||||
|
||||
if (entity == null) {
|
||||
throw new MappingException(String.format("Could not lookup mapping metadata for domain class %s!",
|
||||
domainClass.getName()));
|
||||
}
|
||||
|
||||
return new MappingMongoEntityInformation<T, ID>((MongoPersistentEntity<T>) entity);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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());
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -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.
|
||||
@@ -34,7 +34,6 @@ import org.springframework.data.mongodb.core.query.Criteria;
|
||||
import org.springframework.data.mongodb.core.query.Query;
|
||||
import org.springframework.data.mongodb.repository.MongoRepository;
|
||||
import org.springframework.data.mongodb.repository.query.MongoEntityInformation;
|
||||
import org.springframework.data.mongodb.repository.query.QueryUtils;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
@@ -115,8 +114,11 @@ public class SimpleMongoRepository<T, ID extends Serializable> implements MongoR
|
||||
public boolean exists(ID id) {
|
||||
|
||||
Assert.notNull(id, "The given id must not be null!");
|
||||
return mongoOperations.findOne(new Query(Criteria.where("_id").is(id)), Object.class,
|
||||
entityInformation.getCollectionName()) != null;
|
||||
|
||||
final Query idQuery = getIdQuery(id);
|
||||
idQuery.fields();
|
||||
|
||||
return mongoOperations.findOne(idQuery, entityInformation.getJavaType(), entityInformation.getCollectionName()) != null;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -197,7 +199,7 @@ public class SimpleMongoRepository<T, ID extends Serializable> implements MongoR
|
||||
public Page<T> findAll(final Pageable pageable) {
|
||||
|
||||
Long count = count();
|
||||
List<T> list = findAll(QueryUtils.applyPagination(new Query(), pageable));
|
||||
List<T> list = findAll(new Query().with(pageable));
|
||||
|
||||
return new PageImpl<T>(list, pageable, count);
|
||||
}
|
||||
@@ -206,9 +208,8 @@ public class SimpleMongoRepository<T, ID extends Serializable> implements MongoR
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.repository.PagingAndSortingRepository#findAll(org.springframework.data.domain.Sort)
|
||||
*/
|
||||
public List<T> findAll(final Sort sort) {
|
||||
|
||||
return findAll(QueryUtils.applySorting(new Query(), sort));
|
||||
public List<T> findAll(Sort sort) {
|
||||
return findAll(new Query().with(sort));
|
||||
}
|
||||
|
||||
private List<T> findAll(Query query) {
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
<xsd:import namespace="http://www.springframework.org/schema/context"
|
||||
schemaLocation="http://www.springframework.org/schema/context/spring-context.xsd" />
|
||||
<xsd:import namespace="http://www.springframework.org/schema/data/repository"
|
||||
schemaLocation="http://www.springframework.org/schema/data/repository/spring-repository.xsd" />
|
||||
schemaLocation="http://www.springframework.org/schema/data/repository/spring-repository-1.0.xsd" />
|
||||
|
||||
<xsd:element name="mongo" type="mongoType">
|
||||
<xsd:annotation>
|
||||
@@ -44,8 +44,9 @@ The name of the mongo definition (by default "mongoDbFactory").]]></xsd:document
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="mongo-ref" type="mongoRef" use="optional">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation>
|
||||
The reference to a Mongo. Will default to 'mongo'.
|
||||
<xsd:documentation><![CDATA[
|
||||
The reference to a Mongo instance. If not configured a default com.mongodb.Mongo instance will be created.
|
||||
]]>
|
||||
</xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
|
||||
@@ -44,8 +44,9 @@ The name of the mongo definition (by default "mongoDbFactory").]]></xsd:document
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="mongo-ref" type="mongoRef" use="optional">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation>
|
||||
The reference to a Mongo. Will default to 'mongo'.
|
||||
<xsd:documentation><![CDATA[
|
||||
The reference to a Mongo instance. If not configured a default com.mongodb.Mongo instance will be created.
|
||||
]]>
|
||||
</xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
|
||||
@@ -0,0 +1,483 @@
|
||||
<?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"
|
||||
schemaLocation="http://www.springframework.org/schema/context/spring-context.xsd" />
|
||||
<xsd:import namespace="http://www.springframework.org/schema/data/repository"
|
||||
schemaLocation="http://www.springframework.org/schema/data/repository/spring-repository.xsd" />
|
||||
|
||||
<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:ID" 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:ID" 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:ID" 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>
|
||||
@@ -0,0 +1,97 @@
|
||||
/*
|
||||
* 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.Matchers.*;
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.data.mongodb.core.mapping.Document;
|
||||
|
||||
import com.mongodb.Mongo;
|
||||
|
||||
/**
|
||||
* Unit tests for {@link AbstractMongoConfiguration}.
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
public class AbstractMongoConfigurationUnitTests {
|
||||
|
||||
/**
|
||||
* @see DATAMONGO-496
|
||||
*/
|
||||
@Test
|
||||
public void usesConfigClassPackageAsBaseMappingPackage() throws ClassNotFoundException {
|
||||
|
||||
AbstractMongoConfiguration configuration = new SampleMongoConfiguration();
|
||||
assertThat(configuration.getMappingBasePackage(), is(SampleMongoConfiguration.class.getPackage().getName()));
|
||||
assertThat(configuration.getInitialEntitySet(), hasSize(1));
|
||||
assertThat(configuration.getInitialEntitySet(), hasItem(Entity.class));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATAMONGO-496
|
||||
*/
|
||||
@Test
|
||||
public void doesNotScanPackageIfMappingPackageIsNull() throws ClassNotFoundException {
|
||||
|
||||
assertScanningDisabled(null);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATAMONGO-496
|
||||
*/
|
||||
@Test
|
||||
public void doesNotScanPackageIfMappingPackageIsEmpty() throws ClassNotFoundException {
|
||||
|
||||
assertScanningDisabled("");
|
||||
assertScanningDisabled(" ");
|
||||
}
|
||||
|
||||
private static void assertScanningDisabled(final String value) throws ClassNotFoundException {
|
||||
|
||||
AbstractMongoConfiguration configuration = new SampleMongoConfiguration() {
|
||||
@Override
|
||||
protected String getMappingBasePackage() {
|
||||
return value;
|
||||
}
|
||||
};
|
||||
|
||||
assertThat(configuration.getMappingBasePackage(), is(value));
|
||||
assertThat(configuration.getInitialEntitySet(), hasSize(0));
|
||||
}
|
||||
|
||||
static class SampleMongoConfiguration extends AbstractMongoConfiguration {
|
||||
|
||||
@Override
|
||||
protected String getDatabaseName() {
|
||||
return "database";
|
||||
}
|
||||
|
||||
@Bean
|
||||
@Override
|
||||
public Mongo mongo() throws Exception {
|
||||
return new Mongo();
|
||||
}
|
||||
}
|
||||
|
||||
@Document
|
||||
static class Entity {
|
||||
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,81 @@
|
||||
/*
|
||||
* Copyright 2012 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.data.mongodb.core;
|
||||
|
||||
import static org.hamcrest.Matchers.*;
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import com.mongodb.BasicDBList;
|
||||
import com.mongodb.DBObject;
|
||||
|
||||
/**
|
||||
* Helper classes to ease assertions on {@link DBObject}s.
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
public abstract class DBObjectUtils {
|
||||
|
||||
private DBObjectUtils() {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Expects the field with the given key to be not {@literal null} and a {@link DBObject} in turn and returns it.
|
||||
*
|
||||
* @param source the {@link DBObject} to lookup the nested one
|
||||
* @param key the key of the field to lokup the nested {@link DBObject}
|
||||
* @return
|
||||
*/
|
||||
public static DBObject getAsDBObject(DBObject source, String key) {
|
||||
return getTypedValue(source, key, DBObject.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* Expects the field with the given key to be not {@literal null} and a {@link BasicDBList}.
|
||||
*
|
||||
* @param source the {@link DBObject} to lookup the {@link BasicDBList} in
|
||||
* @param key the key of the field to find the {@link BasicDBList} in
|
||||
* @return
|
||||
*/
|
||||
public static BasicDBList getAsDBList(DBObject source, String key) {
|
||||
return getTypedValue(source, key, BasicDBList.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* Expects the list element with the given index to be a non-{@literal null} {@link DBObject} and returns it.
|
||||
*
|
||||
* @param source the {@link BasicDBList} to look up the {@link DBObject} element in
|
||||
* @param index the index of the element expected to contain a {@link DBObject}
|
||||
* @return
|
||||
*/
|
||||
public static DBObject getAsDBObject(BasicDBList source, int index) {
|
||||
|
||||
assertThat(source.size(), greaterThanOrEqualTo(index + 1));
|
||||
Object value = source.get(index);
|
||||
assertThat(value, is(instanceOf(DBObject.class)));
|
||||
return (DBObject) value;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private static <T> T getTypedValue(DBObject source, String key, Class<T> type) {
|
||||
|
||||
Object value = source.get(key);
|
||||
assertThat(value, is(notNullValue()));
|
||||
assertThat(value, is(instanceOf(type)));
|
||||
|
||||
return (T) value;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,124 @@
|
||||
/*
|
||||
* Copyright 2012 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.data.mongodb.core;
|
||||
|
||||
import static org.hamcrest.CoreMatchers.*;
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.Callable;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
|
||||
import org.junit.AfterClass;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
import org.springframework.dao.DataAccessException;
|
||||
import org.springframework.data.authentication.UserCredentials;
|
||||
import org.springframework.scheduling.concurrent.ThreadPoolExecutorFactoryBean;
|
||||
|
||||
import com.mongodb.DB;
|
||||
import com.mongodb.Mongo;
|
||||
import com.mongodb.MongoException;
|
||||
|
||||
/**
|
||||
* Integration tests for {@link MongoDbUtils}.
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
public class MongoDbUtilsIntegrationTests {
|
||||
|
||||
static final String DATABASE_NAME = "dbAuthTests";
|
||||
static final UserCredentials CREDENTIALS = new UserCredentials("admin", "admin");
|
||||
|
||||
static Mongo mongo;
|
||||
static MongoTemplate template;
|
||||
static ThreadPoolExecutorFactoryBean factory;
|
||||
static ExecutorService service;
|
||||
|
||||
Exception exception;
|
||||
|
||||
@BeforeClass
|
||||
public static void setUp() throws Exception {
|
||||
|
||||
mongo = new Mongo();
|
||||
template = new MongoTemplate(mongo, DATABASE_NAME);
|
||||
|
||||
// Create sample user
|
||||
template.execute(new DbCallback<Void>() {
|
||||
public Void doInDB(DB db) throws MongoException, DataAccessException {
|
||||
db.addUser("admin", "admin".toCharArray());
|
||||
return null;
|
||||
}
|
||||
});
|
||||
|
||||
factory = new ThreadPoolExecutorFactoryBean();
|
||||
factory.setCorePoolSize(2);
|
||||
factory.setMaxPoolSize(10);
|
||||
factory.setWaitForTasksToCompleteOnShutdown(true);
|
||||
factory.afterPropertiesSet();
|
||||
|
||||
service = factory.getObject();
|
||||
}
|
||||
|
||||
@AfterClass
|
||||
public static void tearDown() {
|
||||
|
||||
factory.destroy();
|
||||
|
||||
// Remove test database
|
||||
|
||||
template.execute(new DbCallback<Void>() {
|
||||
public Void doInDB(DB db) throws MongoException, DataAccessException {
|
||||
db.dropDatabase();
|
||||
return null;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATAMONGO-585
|
||||
*/
|
||||
@Test
|
||||
public void authenticatesCorrectlyInMultithreadedEnvironment() throws Exception {
|
||||
|
||||
Callable<Void> callable = new Callable<Void>() {
|
||||
public Void call() throws Exception {
|
||||
|
||||
try {
|
||||
DB db = MongoDbUtils.getDB(mongo, DATABASE_NAME, CREDENTIALS);
|
||||
assertThat(db, is(notNullValue()));
|
||||
} catch (Exception o_O) {
|
||||
MongoDbUtilsIntegrationTests.this.exception = o_O;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
};
|
||||
|
||||
List<Callable<Void>> callables = new ArrayList<Callable<Void>>();
|
||||
|
||||
for (int i = 0; i < 10; i++) {
|
||||
callables.add(callable);
|
||||
}
|
||||
|
||||
service.invokeAll(callables);
|
||||
|
||||
if (exception != null) {
|
||||
fail("Exception occurred!" + exception);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -17,10 +17,17 @@ package org.springframework.data.mongodb.core;
|
||||
|
||||
import static org.hamcrest.CoreMatchers.*;
|
||||
import static org.junit.Assert.*;
|
||||
import static org.mockito.Matchers.*;
|
||||
import static org.mockito.Mockito.*;
|
||||
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.invocation.InvocationOnMock;
|
||||
import org.mockito.runners.MockitoJUnitRunner;
|
||||
import org.mockito.stubbing.Answer;
|
||||
import org.springframework.transaction.support.TransactionSynchronizationManager;
|
||||
|
||||
import com.mongodb.DB;
|
||||
@@ -31,13 +38,21 @@ import com.mongodb.Mongo;
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
@RunWith(MockitoJUnitRunner.class)
|
||||
public class MongoDbUtilsUnitTests {
|
||||
|
||||
@Mock
|
||||
Mongo mongo;
|
||||
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
this.mongo = new Mongo();
|
||||
|
||||
when(mongo.getDB(anyString())).then(new Answer<DB>() {
|
||||
public DB answer(InvocationOnMock invocation) throws Throwable {
|
||||
return mock(DB.class);
|
||||
}
|
||||
});
|
||||
|
||||
TransactionSynchronizationManager.initSynchronization();
|
||||
}
|
||||
|
||||
@@ -55,11 +70,15 @@ public class MongoDbUtilsUnitTests {
|
||||
public void returnsNewInstanceForDifferentDatabaseName() {
|
||||
|
||||
DB first = MongoDbUtils.getDB(mongo, "first");
|
||||
assertThat(first, is(notNullValue()));
|
||||
assertThat(MongoDbUtils.getDB(mongo, "first"), is(first));
|
||||
|
||||
DB second = MongoDbUtils.getDB(mongo, "second");
|
||||
assertThat(second, is(not(first)));
|
||||
assertThat(MongoDbUtils.getDB(mongo, "second"), is(second));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void returnsSameInstanceForSameDatabaseName() {
|
||||
|
||||
DB first = MongoDbUtils.getDB(mongo, "first");
|
||||
assertThat(first, is(notNullValue()));
|
||||
assertThat(MongoDbUtils.getDB(mongo, "first"), is(sameInstance(first)));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,159 @@
|
||||
/*
|
||||
* 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;
|
||||
|
||||
import static org.hamcrest.CoreMatchers.*;
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.UnknownHostException;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.springframework.core.NestedRuntimeException;
|
||||
import org.springframework.dao.DataAccessException;
|
||||
import org.springframework.dao.DataAccessResourceFailureException;
|
||||
import org.springframework.dao.DuplicateKeyException;
|
||||
import org.springframework.dao.InvalidDataAccessApiUsageException;
|
||||
import org.springframework.dao.InvalidDataAccessResourceUsageException;
|
||||
import org.springframework.data.mongodb.UncategorizedMongoDbException;
|
||||
|
||||
import com.mongodb.MongoException;
|
||||
import com.mongodb.MongoException.DuplicateKey;
|
||||
import com.mongodb.MongoException.Network;
|
||||
import com.mongodb.MongoInternalException;
|
||||
import com.mongodb.ServerAddress;
|
||||
|
||||
/**
|
||||
* Unit tests for {@link MongoExceptionTranslator}.
|
||||
*
|
||||
* @author Michal Vich
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
public class MongoExceptionTranslatorUnitTests {
|
||||
|
||||
MongoExceptionTranslator translator;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
translator = new MongoExceptionTranslator();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void translateDuplicateKey() {
|
||||
|
||||
DuplicateKey exception = new DuplicateKey(1, "Duplicated key");
|
||||
DataAccessException translatedException = translator.translateExceptionIfPossible(exception);
|
||||
|
||||
expectExceptionWithCauseMessage(translatedException, DuplicateKeyException.class, "Duplicated key");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void translateNetwork() {
|
||||
|
||||
Network exception = new Network("IOException", new IOException("IOException"));
|
||||
DataAccessException translatedException = translator.translateExceptionIfPossible(exception);
|
||||
|
||||
expectExceptionWithCauseMessage(translatedException, DataAccessResourceFailureException.class, "IOException");
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void translateCursorNotFound() throws UnknownHostException {
|
||||
|
||||
MongoException.CursorNotFound exception = new MongoException.CursorNotFound(1, new ServerAddress());
|
||||
DataAccessException translatedException = translator.translateExceptionIfPossible(exception);
|
||||
|
||||
expectExceptionWithCauseMessage(translatedException, DataAccessResourceFailureException.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void translateToDuplicateKeyException() {
|
||||
|
||||
checkTranslatedMongoException(DuplicateKeyException.class, 11000);
|
||||
checkTranslatedMongoException(DuplicateKeyException.class, 11001);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void translateToDataAccessResourceFailureException() {
|
||||
|
||||
checkTranslatedMongoException(DataAccessResourceFailureException.class, 12000);
|
||||
checkTranslatedMongoException(DataAccessResourceFailureException.class, 13440);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void translateToInvalidDataAccessApiUsageException() {
|
||||
|
||||
checkTranslatedMongoException(InvalidDataAccessApiUsageException.class, 10003);
|
||||
checkTranslatedMongoException(InvalidDataAccessApiUsageException.class, 12001);
|
||||
checkTranslatedMongoException(InvalidDataAccessApiUsageException.class, 12010);
|
||||
checkTranslatedMongoException(InvalidDataAccessApiUsageException.class, 12011);
|
||||
checkTranslatedMongoException(InvalidDataAccessApiUsageException.class, 12012);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void translateToUncategorizedMongoDbException() {
|
||||
|
||||
MongoException exception = new MongoException(0, "");
|
||||
DataAccessException translatedException = translator.translateExceptionIfPossible(exception);
|
||||
|
||||
expectExceptionWithCauseMessage(translatedException, UncategorizedMongoDbException.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void translateMongoInternalException() {
|
||||
|
||||
MongoInternalException exception = new MongoInternalException("Internal exception");
|
||||
DataAccessException translatedException = translator.translateExceptionIfPossible(exception);
|
||||
|
||||
expectExceptionWithCauseMessage(translatedException, InvalidDataAccessResourceUsageException.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void translateUnsupportedException() {
|
||||
|
||||
RuntimeException exception = new RuntimeException();
|
||||
assertThat(translator.translateExceptionIfPossible(exception), is(nullValue()));
|
||||
}
|
||||
|
||||
private void checkTranslatedMongoException(Class<? extends Exception> clazz, int code) {
|
||||
|
||||
try {
|
||||
translator.translateExceptionIfPossible(new MongoException(code, ""));
|
||||
fail("Expected exception of type " + clazz.getName() + "!");
|
||||
} catch (NestedRuntimeException e) {
|
||||
Throwable cause = e.getRootCause();
|
||||
assertThat(cause, is(instanceOf(MongoException.class)));
|
||||
assertThat(((MongoException) cause).getCode(), is(code));
|
||||
}
|
||||
}
|
||||
|
||||
private static void expectExceptionWithCauseMessage(NestedRuntimeException e,
|
||||
Class<? extends NestedRuntimeException> type) {
|
||||
expectExceptionWithCauseMessage(e, type, null);
|
||||
}
|
||||
|
||||
private static void expectExceptionWithCauseMessage(NestedRuntimeException e,
|
||||
Class<? extends NestedRuntimeException> type, String message) {
|
||||
|
||||
assertThat(e, is(instanceOf(type)));
|
||||
|
||||
if (message != null) {
|
||||
assertThat(e.getRootCause(), is(notNullValue()));
|
||||
assertThat(e.getRootCause().getMessage(), containsString(message));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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.
|
||||
@@ -34,6 +34,7 @@ import org.springframework.data.mongodb.core.geo.Point;
|
||||
import org.springframework.data.mongodb.core.mapping.MongoPersistentEntity;
|
||||
import org.springframework.data.mongodb.core.mapping.MongoPersistentProperty;
|
||||
import org.springframework.data.mongodb.core.query.NearQuery;
|
||||
import org.springframework.data.util.TypeInformation;
|
||||
|
||||
import com.mongodb.BasicDBObject;
|
||||
import com.mongodb.DBObject;
|
||||
@@ -78,7 +79,7 @@ public abstract class MongoOperationsUnitTests {
|
||||
return null;
|
||||
}
|
||||
|
||||
public Object convertToMongoType(Object obj) {
|
||||
public Object convertToMongoType(Object obj, TypeInformation<?> typeInformation) {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
@@ -24,8 +24,10 @@ import static org.springframework.data.mongodb.core.query.Update.*;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.bson.types.ObjectId;
|
||||
import org.joda.time.DateTime;
|
||||
@@ -40,8 +42,11 @@ 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.InvalidDataAccessApiUsageException;
|
||||
import org.springframework.dao.OptimisticLockingFailureException;
|
||||
import org.springframework.data.annotation.Id;
|
||||
import org.springframework.data.annotation.PersistenceConstructor;
|
||||
import org.springframework.data.mapping.model.MappingException;
|
||||
import org.springframework.data.mongodb.InvalidMongoDbApiUsageException;
|
||||
import org.springframework.data.mongodb.MongoDbFactory;
|
||||
import org.springframework.data.mongodb.core.convert.CustomConversions;
|
||||
@@ -51,6 +56,7 @@ 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.MongoMappingContext;
|
||||
import org.springframework.data.mongodb.core.query.BasicQuery;
|
||||
import org.springframework.data.mongodb.core.query.Criteria;
|
||||
import org.springframework.data.mongodb.core.query.Order;
|
||||
import org.springframework.data.mongodb.core.query.Query;
|
||||
@@ -58,6 +64,7 @@ import org.springframework.data.mongodb.core.query.Update;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
|
||||
import com.mongodb.BasicDBObject;
|
||||
import com.mongodb.DBCollection;
|
||||
import com.mongodb.DBCursor;
|
||||
import com.mongodb.DBObject;
|
||||
@@ -74,6 +81,7 @@ import com.mongodb.WriteResult;
|
||||
* @author Oliver Gierke
|
||||
* @author Thomas Risberg
|
||||
* @author Amol Nayak
|
||||
* @author Patryk Wasik
|
||||
*/
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
@ContextConfiguration("classpath:infrastructure.xml")
|
||||
@@ -123,18 +131,21 @@ public class MongoTemplateTests {
|
||||
}
|
||||
|
||||
protected void cleanDb() {
|
||||
template.dropCollection(template.getCollectionName(Person.class));
|
||||
template.dropCollection(template.getCollectionName(PersonWithAList.class));
|
||||
template.dropCollection(template.getCollectionName(PersonWith_idPropertyOfTypeObjectId.class));
|
||||
template.dropCollection(template.getCollectionName(PersonWith_idPropertyOfTypeString.class));
|
||||
template.dropCollection(template.getCollectionName(PersonWithIdPropertyOfTypeObjectId.class));
|
||||
template.dropCollection(template.getCollectionName(PersonWithIdPropertyOfTypeString.class));
|
||||
template.dropCollection(template.getCollectionName(PersonWithIdPropertyOfTypeInteger.class));
|
||||
template.dropCollection(template.getCollectionName(PersonWithIdPropertyOfPrimitiveInt.class));
|
||||
template.dropCollection(template.getCollectionName(PersonWithIdPropertyOfTypeLong.class));
|
||||
template.dropCollection(template.getCollectionName(PersonWithIdPropertyOfPrimitiveLong.class));
|
||||
template.dropCollection(template.getCollectionName(TestClass.class));
|
||||
template.dropCollection(Person.class);
|
||||
template.dropCollection(PersonWithAList.class);
|
||||
template.dropCollection(PersonWith_idPropertyOfTypeObjectId.class);
|
||||
template.dropCollection(PersonWith_idPropertyOfTypeString.class);
|
||||
template.dropCollection(PersonWithIdPropertyOfTypeObjectId.class);
|
||||
template.dropCollection(PersonWithIdPropertyOfTypeString.class);
|
||||
template.dropCollection(PersonWithIdPropertyOfTypeInteger.class);
|
||||
template.dropCollection(PersonWithIdPropertyOfPrimitiveInt.class);
|
||||
template.dropCollection(PersonWithIdPropertyOfTypeLong.class);
|
||||
template.dropCollection(PersonWithIdPropertyOfPrimitiveLong.class);
|
||||
template.dropCollection(PersonWithVersionPropertyOfTypeInteger.class);
|
||||
template.dropCollection(TestClass.class);
|
||||
template.dropCollection(Sample.class);
|
||||
template.dropCollection(MyPerson.class);
|
||||
template.dropCollection("collection");
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -201,19 +212,14 @@ public class MongoTemplateTests {
|
||||
|
||||
template.insert(person);
|
||||
|
||||
try {
|
||||
thrown.expect(DataIntegrityViolationException.class);
|
||||
thrown.expectMessage("Execution");
|
||||
thrown.expectMessage("$push");
|
||||
thrown.expectMessage("firstName");
|
||||
|
||||
Query query = new Query(Criteria.where("firstName").is("Amol"));
|
||||
Update upd = new Update().push("age", 29);
|
||||
template.updateFirst(query, upd, Person.class);
|
||||
fail("Expected DataIntegrityViolationException!");
|
||||
|
||||
} catch (DataIntegrityViolationException e) {
|
||||
|
||||
assertThat(e.getMessage(),
|
||||
is("Execution of update with '{ \"$push\" : { \"age\" : 29}}'' using '{ \"firstName\" : \"Amol\"}' "
|
||||
+ "query failed: Cannot apply $push/$pushAll modifier to non-array"));
|
||||
}
|
||||
Query query = new Query(Criteria.where("firstName").is("Amol"));
|
||||
Update upd = new Update().push("age", 29);
|
||||
template.updateFirst(query, upd, Person.class);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1017,7 +1023,7 @@ public class MongoTemplateTests {
|
||||
assertThat(lastMongoAction.getCollectionName(), is("personWithIdPropertyOfTypeObjectId"));
|
||||
assertThat(lastMongoAction.getDefaultWriteConcern(), equalTo(WriteConcern.NONE));
|
||||
assertThat(lastMongoAction.getDocument(), notNullValue());
|
||||
assertThat(lastMongoAction.getEntityClass().toString(), is(PersonWithIdPropertyOfTypeObjectId.class.toString()));
|
||||
assertThat(lastMongoAction.getEntityType().toString(), is(PersonWithIdPropertyOfTypeObjectId.class.toString()));
|
||||
assertThat(lastMongoAction.getMongoActionOperation(), is(MongoActionOperation.UPDATE));
|
||||
assertThat(lastMongoAction.getQuery(), equalTo(q.getQueryObject()));
|
||||
|
||||
@@ -1232,6 +1238,223 @@ public class MongoTemplateTests {
|
||||
template.remove(query(where("id").is(id)), TypeWithMyId.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATAMONGO-506
|
||||
*/
|
||||
@Test
|
||||
public void exceutesBasicQueryCorrectly() {
|
||||
|
||||
Address address = new Address();
|
||||
address.state = "PA";
|
||||
address.city = "Philadelphia";
|
||||
|
||||
MyPerson person = new MyPerson();
|
||||
person.name = "Oleg";
|
||||
person.address = address;
|
||||
|
||||
template.save(person);
|
||||
|
||||
Query query = new BasicQuery("{'name' : 'Oleg'}");
|
||||
List<MyPerson> result = template.find(query, MyPerson.class);
|
||||
|
||||
assertThat(result, hasSize(1));
|
||||
assertThat(result.get(0), hasProperty("name", is("Oleg")));
|
||||
|
||||
query = new BasicQuery("{'address.state' : 'PA' }");
|
||||
result = template.find(query, MyPerson.class);
|
||||
|
||||
assertThat(result, hasSize(1));
|
||||
assertThat(result.get(0), hasProperty("name", is("Oleg")));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATAMONGO-279
|
||||
*/
|
||||
@Test(expected = OptimisticLockingFailureException.class)
|
||||
public void optimisticLockingHandling() {
|
||||
|
||||
// Init version
|
||||
PersonWithVersionPropertyOfTypeInteger person = new PersonWithVersionPropertyOfTypeInteger();
|
||||
person.age = 29;
|
||||
person.firstName = "Patryk";
|
||||
template.save(person);
|
||||
|
||||
List<PersonWithVersionPropertyOfTypeInteger> result = template
|
||||
.findAll(PersonWithVersionPropertyOfTypeInteger.class);
|
||||
|
||||
assertThat(result, hasSize(1));
|
||||
assertThat(result.get(0).version, is(0));
|
||||
|
||||
// Version change
|
||||
person = result.get(0);
|
||||
person.firstName = "Patryk2";
|
||||
|
||||
template.save(person);
|
||||
|
||||
assertThat(person.version, is(1));
|
||||
|
||||
result = mappingTemplate.findAll(PersonWithVersionPropertyOfTypeInteger.class);
|
||||
|
||||
assertThat(result, hasSize(1));
|
||||
assertThat(result.get(0).version, is(1));
|
||||
|
||||
// Optimistic lock exception
|
||||
person.version = 0;
|
||||
person.firstName = "Patryk3";
|
||||
|
||||
template.save(person);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATAMONGO-562
|
||||
*/
|
||||
@Test
|
||||
public void optimisticLockingHandlingWithExistingId() {
|
||||
|
||||
PersonWithVersionPropertyOfTypeInteger person = new PersonWithVersionPropertyOfTypeInteger();
|
||||
person.id = new ObjectId().toString();
|
||||
person.age = 29;
|
||||
person.firstName = "Patryk";
|
||||
template.save(person);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATAMONGO-539
|
||||
*/
|
||||
@Test
|
||||
public void removesObjectFromExplicitCollection() {
|
||||
|
||||
String collectionName = "explicit";
|
||||
template.remove(new Query(), collectionName);
|
||||
|
||||
PersonWithConvertedId person = new PersonWithConvertedId();
|
||||
person.name = "Dave";
|
||||
template.save(person, collectionName);
|
||||
assertThat(template.findAll(PersonWithConvertedId.class, collectionName).isEmpty(), is(false));
|
||||
|
||||
template.remove(person, collectionName);
|
||||
assertThat(template.findAll(PersonWithConvertedId.class, collectionName).isEmpty(), is(true));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATAMONGO-549
|
||||
*/
|
||||
public void savesMapCorrectly() {
|
||||
|
||||
Map<String, String> map = new HashMap<String, String>();
|
||||
map.put("key", "value");
|
||||
|
||||
template.save(map, "maps");
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATAMONGO-549
|
||||
*/
|
||||
@Test(expected = MappingException.class)
|
||||
public void savesMongoPrimitiveObjectCorrectly() {
|
||||
template.save(new Object(), "collection");
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATAMONGO-549
|
||||
*/
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void rejectsNullObjectToBeSaved() {
|
||||
template.save(null);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATAMONGO-550
|
||||
*/
|
||||
@Test
|
||||
public void savesPlainDbObjectCorrectly() {
|
||||
|
||||
DBObject dbObject = new BasicDBObject("foo", "bar");
|
||||
template.save(dbObject, "collection");
|
||||
|
||||
assertThat(dbObject.containsField("_id"), is(true));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATAMONGO-550
|
||||
*/
|
||||
@Test(expected = InvalidDataAccessApiUsageException.class)
|
||||
public void rejectsPlainObjectWithOutExplicitCollection() {
|
||||
|
||||
DBObject dbObject = new BasicDBObject("foo", "bar");
|
||||
template.save(dbObject, "collection");
|
||||
|
||||
template.findById(dbObject.get("_id"), DBObject.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATAMONGO-550
|
||||
*/
|
||||
@Test
|
||||
public void readsPlainDbObjectById() {
|
||||
|
||||
DBObject dbObject = new BasicDBObject("foo", "bar");
|
||||
template.save(dbObject, "collection");
|
||||
|
||||
DBObject result = template.findById(dbObject.get("_id"), DBObject.class, "collection");
|
||||
assertThat(result.get("foo"), is(dbObject.get("foo")));
|
||||
assertThat(result.get("_id"), is(dbObject.get("_id")));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATAMONGO-551
|
||||
*/
|
||||
@Test
|
||||
public void writesPlainString() {
|
||||
template.save("{ 'foo' : 'bar' }", "collection");
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATAMONGO-551
|
||||
*/
|
||||
@Test(expected = MappingException.class)
|
||||
public void rejectsNonJsonStringForSave() {
|
||||
template.save("Foobar!", "collection");
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATAMONGO-588
|
||||
*/
|
||||
@Test
|
||||
public void initializesVersionOnInsert() {
|
||||
|
||||
PersonWithVersionPropertyOfTypeInteger person = new PersonWithVersionPropertyOfTypeInteger();
|
||||
person.firstName = "Dave";
|
||||
|
||||
template.insert(person);
|
||||
|
||||
assertThat(person.version, is(0));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATAMONGO-588
|
||||
*/
|
||||
@Test
|
||||
public void initializesVersionOnBatchInsert() {
|
||||
|
||||
PersonWithVersionPropertyOfTypeInteger person = new PersonWithVersionPropertyOfTypeInteger();
|
||||
person.firstName = "Dave";
|
||||
|
||||
template.insertAll(Arrays.asList(person));
|
||||
|
||||
assertThat(person.version, is(0));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATAMONGO-568
|
||||
*/
|
||||
@Test
|
||||
public void queryCantBeNull() {
|
||||
|
||||
List<PersonWithIdPropertyOfTypeObjectId> result = template.findAll(PersonWithIdPropertyOfTypeObjectId.class);
|
||||
assertThat(template.find(null, PersonWithIdPropertyOfTypeObjectId.class), is(result));
|
||||
}
|
||||
|
||||
static class MyId {
|
||||
|
||||
String first;
|
||||
@@ -1261,6 +1484,12 @@ public class MongoTemplateTests {
|
||||
}
|
||||
}
|
||||
|
||||
static class PersonWithConvertedId {
|
||||
|
||||
String id;
|
||||
String name;
|
||||
}
|
||||
|
||||
static enum DateTimeToDateConverter implements Converter<DateTime, Date> {
|
||||
|
||||
INSTANCE;
|
||||
@@ -1278,4 +1507,21 @@ public class MongoTemplateTests {
|
||||
return source == null ? null : new DateTime(source.getTime());
|
||||
}
|
||||
}
|
||||
|
||||
public static class MyPerson {
|
||||
|
||||
String id;
|
||||
String name;
|
||||
Address address;
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
}
|
||||
|
||||
static class Address {
|
||||
|
||||
String state;
|
||||
String city;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,12 +15,13 @@
|
||||
*/
|
||||
package org.springframework.data.mongodb.core;
|
||||
|
||||
import static org.hamcrest.CoreMatchers.*;
|
||||
import static org.hamcrest.Matchers.*;
|
||||
import static org.junit.Assert.*;
|
||||
import static org.mockito.Matchers.*;
|
||||
import static org.mockito.Mockito.*;
|
||||
|
||||
import java.math.BigInteger;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
@@ -31,6 +32,7 @@ import org.junit.runner.RunWith;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.Mockito;
|
||||
import org.mockito.runners.MockitoJUnitRunner;
|
||||
import org.springframework.context.ApplicationListener;
|
||||
import org.springframework.context.support.GenericApplicationContext;
|
||||
import org.springframework.core.convert.converter.Converter;
|
||||
import org.springframework.dao.DataAccessException;
|
||||
@@ -40,6 +42,7 @@ import org.springframework.data.mongodb.MongoDbFactory;
|
||||
import org.springframework.data.mongodb.core.convert.CustomConversions;
|
||||
import org.springframework.data.mongodb.core.convert.MappingMongoConverter;
|
||||
import org.springframework.data.mongodb.core.convert.QueryMapper;
|
||||
import org.springframework.data.mongodb.core.index.MongoPersistentEntityIndexCreator;
|
||||
import org.springframework.data.mongodb.core.mapping.MongoMappingContext;
|
||||
import org.springframework.data.mongodb.core.query.Query;
|
||||
import org.springframework.data.mongodb.core.query.Update;
|
||||
@@ -71,11 +74,13 @@ public class MongoTemplateUnitTests extends MongoOperationsUnitTests {
|
||||
DBCollection collection;
|
||||
|
||||
MappingMongoConverter converter;
|
||||
MongoMappingContext mappingContext;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
|
||||
this.converter = new MappingMongoConverter(factory, new MongoMappingContext());
|
||||
this.mappingContext = new MongoMappingContext();
|
||||
this.converter = new MappingMongoConverter(factory, mappingContext);
|
||||
this.template = new MongoTemplate(factory, converter);
|
||||
|
||||
when(factory.getDb()).thenReturn(db);
|
||||
@@ -198,6 +203,29 @@ public class MongoTemplateUnitTests extends MongoOperationsUnitTests {
|
||||
assertThat(entity.id, is(5));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATAMONGO-533
|
||||
*/
|
||||
@Test
|
||||
public void registersDefaultEntityIndexCreatorIfApplicationContextHasOneForDifferentMappingContext() {
|
||||
|
||||
GenericApplicationContext applicationContext = new GenericApplicationContext();
|
||||
applicationContext.getBeanFactory().registerSingleton("foo",
|
||||
new MongoPersistentEntityIndexCreator(new MongoMappingContext(), factory));
|
||||
|
||||
MongoTemplate mongoTemplate = new MongoTemplate(factory, converter);
|
||||
mongoTemplate.setApplicationContext(applicationContext);
|
||||
|
||||
Collection<ApplicationListener<?>> listeners = applicationContext.getApplicationListeners();
|
||||
assertThat(listeners, hasSize(1));
|
||||
|
||||
ApplicationListener<?> listener = listeners.iterator().next();
|
||||
|
||||
assertThat(listener, is(instanceOf(MongoPersistentEntityIndexCreator.class)));
|
||||
MongoPersistentEntityIndexCreator creator = (MongoPersistentEntityIndexCreator) listener;
|
||||
assertThat(creator.isIndexCreatorFor(mappingContext), is(true));
|
||||
}
|
||||
|
||||
class AutogenerateableId {
|
||||
|
||||
@Id
|
||||
|
||||
@@ -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.mongodb.core.mapping.Version;
|
||||
|
||||
public class PersonWithVersionPropertyOfTypeInteger {
|
||||
|
||||
String id;
|
||||
String firstName;
|
||||
int age;
|
||||
|
||||
@Version
|
||||
Integer version;
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "PersonWithVersionPropertyOfTypeInteger [id=" + id + ", firstName=" + firstName + ", age=" + age
|
||||
+ ", version=" + version + "]";
|
||||
}
|
||||
}
|
||||
@@ -17,12 +17,13 @@ package org.springframework.data.mongodb.core;
|
||||
|
||||
import static org.hamcrest.Matchers.*;
|
||||
import static org.junit.Assert.*;
|
||||
import static org.springframework.data.mongodb.core.SerializationUtils.*;
|
||||
import static org.springframework.data.mongodb.core.query.SerializationUtils.*;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
import org.hamcrest.Matcher;
|
||||
import org.junit.Test;
|
||||
import org.springframework.data.mongodb.core.query.SerializationUtils;
|
||||
|
||||
import com.mongodb.BasicDBObject;
|
||||
import com.mongodb.DBObject;
|
||||
|
||||
@@ -21,7 +21,7 @@ public class TestMongoConfiguration extends AbstractMongoConfiguration {
|
||||
@Override
|
||||
@Bean
|
||||
public Mongo mongo() throws Exception {
|
||||
return new Mongo("localhost", 27017);
|
||||
return new Mongo("127.0.0.1", 27017);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -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.
|
||||
@@ -49,10 +49,12 @@ import org.springframework.context.event.ContextRefreshedEvent;
|
||||
import org.springframework.core.convert.converter.Converter;
|
||||
import org.springframework.data.annotation.Id;
|
||||
import org.springframework.data.annotation.PersistenceConstructor;
|
||||
import org.springframework.data.annotation.TypeAlias;
|
||||
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;
|
||||
@@ -64,6 +66,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}.
|
||||
@@ -109,15 +112,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();
|
||||
@@ -135,15 +130,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();
|
||||
@@ -917,7 +904,7 @@ public class MappingMongoConverterUnitTests {
|
||||
Object contacts = result.get("contacts");
|
||||
assertThat(contacts, is(instanceOf(Collection.class)));
|
||||
assertThat(((Collection<?>) contacts).size(), is(2));
|
||||
assertThat(((Collection<Object>) contacts), hasItem(nullValue()));
|
||||
assertThat((Collection<Object>) contacts, hasItem(nullValue()));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1252,6 +1239,18 @@ public class MappingMongoConverterUnitTests {
|
||||
assertThat(values, is(arrayWithSize(2)));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATAMONGO-497
|
||||
*/
|
||||
@Test
|
||||
public void readsEmptyCollectionIntoConstructorCorrectly() {
|
||||
|
||||
DBObject source = new BasicDBObject("attributes", new BasicDBList());
|
||||
|
||||
TypWithCollectionConstructor result = converter.read(TypWithCollectionConstructor.class, source);
|
||||
assertThat(result.attributes, is(notNullValue()));
|
||||
}
|
||||
|
||||
private static void assertSyntheticFieldValueOf(Object target, Object expected) {
|
||||
|
||||
for (int i = 0; i < 10; i++) {
|
||||
@@ -1266,6 +1265,62 @@ public class MappingMongoConverterUnitTests {
|
||||
fail(String.format("Didn't find synthetic field on %s!", target));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATAMGONGO-508
|
||||
*/
|
||||
@Test
|
||||
public void eagerlyReturnsDBRefObjectIfTargetAlreadyIsOne() {
|
||||
|
||||
DB db = mock(DB.class);
|
||||
DBRef dbRef = new DBRef(db, "collection", "id");
|
||||
|
||||
org.springframework.data.mongodb.core.mapping.DBRef annotation = mock(org.springframework.data.mongodb.core.mapping.DBRef.class);
|
||||
|
||||
assertThat(converter.createDBRef(dbRef, annotation), is(dbRef));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATAMONGO-523
|
||||
*/
|
||||
@Test
|
||||
public void considersTypeAliasAnnotation() {
|
||||
|
||||
Aliased aliased = new Aliased();
|
||||
aliased.name = "foo";
|
||||
|
||||
DBObject result = new BasicDBObject();
|
||||
converter.write(aliased, result);
|
||||
|
||||
Object type = result.get("_class");
|
||||
assertThat(type, is(notNullValue()));
|
||||
assertThat(type.toString(), is("_"));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATAMONGO-533
|
||||
*/
|
||||
@Test
|
||||
public void marshalsThrowableCorrectly() {
|
||||
|
||||
ThrowableWrapper wrapper = new ThrowableWrapper();
|
||||
wrapper.throwable = new Exception();
|
||||
|
||||
DBObject dbObject = new BasicDBObject();
|
||||
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;
|
||||
}
|
||||
@@ -1440,6 +1495,57 @@ public class MappingMongoConverterUnitTests {
|
||||
Long innerId;
|
||||
}
|
||||
|
||||
static class TypWithCollectionConstructor {
|
||||
|
||||
List<Attribute> attributes;
|
||||
|
||||
public TypWithCollectionConstructor(List<Attribute> attributes) {
|
||||
this.attributes = attributes;
|
||||
}
|
||||
}
|
||||
|
||||
@TypeAlias("_")
|
||||
static class Aliased {
|
||||
String name;
|
||||
}
|
||||
|
||||
static class ThrowableWrapper {
|
||||
|
||||
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,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,
|
||||
@@ -17,11 +17,14 @@ package org.springframework.data.mongodb.core.convert;
|
||||
|
||||
import static org.hamcrest.Matchers.*;
|
||||
import static org.junit.Assert.*;
|
||||
import static org.springframework.data.mongodb.core.DBObjectUtils.*;
|
||||
import static org.springframework.data.mongodb.core.query.Criteria.*;
|
||||
import static org.springframework.data.mongodb.core.query.Query.*;
|
||||
|
||||
import java.math.BigInteger;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import org.bson.types.ObjectId;
|
||||
import org.junit.Before;
|
||||
@@ -31,7 +34,10 @@ import org.mockito.Mock;
|
||||
import org.mockito.runners.MockitoJUnitRunner;
|
||||
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.DBRef;
|
||||
import org.springframework.data.mongodb.core.mapping.Field;
|
||||
import org.springframework.data.mongodb.core.mapping.MongoMappingContext;
|
||||
import org.springframework.data.mongodb.core.mapping.MongoPersistentEntity;
|
||||
import org.springframework.data.mongodb.core.query.BasicQuery;
|
||||
@@ -49,11 +55,11 @@ import com.mongodb.QueryBuilder;
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
@RunWith(MockitoJUnitRunner.class)
|
||||
@SuppressWarnings("unused")
|
||||
public class QueryMapperUnitTests {
|
||||
|
||||
QueryMapper mapper;
|
||||
MongoMappingContext context;
|
||||
MappingMongoConverter converter;
|
||||
|
||||
@Mock
|
||||
MongoDbFactory factory;
|
||||
@@ -63,7 +69,7 @@ public class QueryMapperUnitTests {
|
||||
|
||||
context = new MongoMappingContext();
|
||||
|
||||
MappingMongoConverter converter = new MappingMongoConverter(factory, context);
|
||||
converter = new MappingMongoConverter(factory, context);
|
||||
converter.afterPropertiesSet();
|
||||
|
||||
mapper = new QueryMapper(converter);
|
||||
@@ -200,7 +206,7 @@ public class QueryMapperUnitTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void doesNotHandleNestedFieldsWithDefaultIdNames() {
|
||||
public void doesHandleNestedFieldsWithDefaultIdNames() {
|
||||
|
||||
BasicDBObject dbObject = new BasicDBObject("id", new ObjectId().toString());
|
||||
dbObject.put("nested", new BasicDBObject("id", new ObjectId().toString()));
|
||||
@@ -209,7 +215,136 @@ public class QueryMapperUnitTests {
|
||||
|
||||
DBObject result = mapper.getMappedObject(dbObject, entity);
|
||||
assertThat(result.get("_id"), is(instanceOf(ObjectId.class)));
|
||||
assertThat(((DBObject) result.get("nested")).get("id"), is(instanceOf(String.class)));
|
||||
assertThat(((DBObject) result.get("nested")).get("_id"), is(instanceOf(ObjectId.class)));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATAMONGO-493
|
||||
*/
|
||||
@Test
|
||||
public void doesNotTranslateNonIdPropertiesFor$NeCriteria() {
|
||||
|
||||
ObjectId accidentallyAnObjectId = new ObjectId();
|
||||
|
||||
Query query = Query.query(Criteria.where("id").is("id_value").and("publishers")
|
||||
.ne(accidentallyAnObjectId.toString()));
|
||||
|
||||
DBObject dbObject = mapper.getMappedObject(query.getQueryObject(), context.getPersistentEntity(UserEntity.class));
|
||||
assertThat(dbObject.get("publishers"), is(instanceOf(DBObject.class)));
|
||||
|
||||
DBObject publishers = (DBObject) dbObject.get("publishers");
|
||||
assertThat(publishers.containsField("$ne"), is(true));
|
||||
assertThat(publishers.get("$ne"), is(instanceOf(String.class)));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATAMONGO-494
|
||||
*/
|
||||
@Test
|
||||
public void usesEntityMetadataInOr() {
|
||||
|
||||
Query query = query(new Criteria().orOperator(where("foo").is("bar")));
|
||||
DBObject result = mapper.getMappedObject(query.getQueryObject(), context.getPersistentEntity(Sample.class));
|
||||
|
||||
assertThat(result.keySet(), hasSize(1));
|
||||
assertThat(result.keySet(), hasItem("$or"));
|
||||
|
||||
BasicDBList ors = getAsDBList(result, "$or");
|
||||
assertThat(ors, hasSize(1));
|
||||
DBObject criterias = getAsDBObject(ors, 0);
|
||||
assertThat(criterias.keySet(), hasSize(1));
|
||||
assertThat(criterias.get("_id"), is(notNullValue()));
|
||||
assertThat(criterias.get("foo"), is(nullValue()));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void translatesPropertyReferenceCorrectly() {
|
||||
|
||||
Query query = query(where("field").is(new CustomizedField()));
|
||||
DBObject result = mapper
|
||||
.getMappedObject(query.getQueryObject(), context.getPersistentEntity(CustomizedField.class));
|
||||
|
||||
assertThat(result.containsField("foo"), is(true));
|
||||
assertThat(result.keySet().size(), is(1));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void translatesNestedPropertyReferenceCorrectly() {
|
||||
|
||||
Query query = query(where("field.field").is(new CustomizedField()));
|
||||
DBObject result = mapper
|
||||
.getMappedObject(query.getQueryObject(), context.getPersistentEntity(CustomizedField.class));
|
||||
|
||||
assertThat(result.containsField("foo.foo"), is(true));
|
||||
assertThat(result.keySet().size(), is(1));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void returnsOriginalKeyIfNoPropertyReference() {
|
||||
|
||||
Query query = query(where("bar").is(new CustomizedField()));
|
||||
DBObject result = mapper
|
||||
.getMappedObject(query.getQueryObject(), context.getPersistentEntity(CustomizedField.class));
|
||||
|
||||
assertThat(result.containsField("bar"), is(true));
|
||||
assertThat(result.keySet().size(), is(1));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void convertsAssociationCorrectly() {
|
||||
|
||||
Reference reference = new Reference();
|
||||
reference.id = 5L;
|
||||
|
||||
Query query = query(where("reference").is(reference));
|
||||
DBObject object = mapper.getMappedObject(query.getQueryObject(), context.getPersistentEntity(WithDBRef.class));
|
||||
|
||||
Object referenceObject = object.get("reference");
|
||||
|
||||
assertThat(referenceObject, is(instanceOf(com.mongodb.DBRef.class)));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void convertsNestedAssociationCorrectly() {
|
||||
|
||||
Reference reference = new Reference();
|
||||
reference.id = 5L;
|
||||
|
||||
Query query = query(where("withDbRef.reference").is(reference));
|
||||
DBObject object = mapper.getMappedObject(query.getQueryObject(),
|
||||
context.getPersistentEntity(WithDBRefWrapper.class));
|
||||
|
||||
Object referenceObject = object.get("withDbRef.reference");
|
||||
|
||||
assertThat(referenceObject, is(instanceOf(com.mongodb.DBRef.class)));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void convertsInKeywordCorrectly() {
|
||||
|
||||
Reference first = new Reference();
|
||||
first.id = 5L;
|
||||
|
||||
Reference second = new Reference();
|
||||
second.id = 6L;
|
||||
|
||||
Query query = query(where("reference").in(first, second));
|
||||
DBObject result = mapper.getMappedObject(query.getQueryObject(), context.getPersistentEntity(WithDBRef.class));
|
||||
|
||||
DBObject reference = DBObjectUtils.getAsDBObject(result, "reference");
|
||||
assertThat(reference.containsField("$in"), is(true));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATAMONGO-570
|
||||
*/
|
||||
@Test
|
||||
public void correctlyConvertsNullReference() {
|
||||
|
||||
Query query = query(where("reference").is(null));
|
||||
DBObject object = mapper.getMappedObject(query.getQueryObject(), context.getPersistentEntity(WithDBRef.class));
|
||||
|
||||
assertThat(object.get("reference"), is(nullValue()));
|
||||
}
|
||||
|
||||
class IdWrapper {
|
||||
@@ -237,4 +372,31 @@ public class QueryMapperUnitTests {
|
||||
enum Enum {
|
||||
INSTANCE;
|
||||
}
|
||||
|
||||
class UserEntity {
|
||||
String id;
|
||||
List<String> publishers = new ArrayList<String>();
|
||||
}
|
||||
|
||||
class CustomizedField {
|
||||
|
||||
@Field("foo")
|
||||
CustomizedField field;
|
||||
}
|
||||
|
||||
class WithDBRef {
|
||||
|
||||
@DBRef
|
||||
Reference reference;
|
||||
}
|
||||
|
||||
class Reference {
|
||||
|
||||
Long id;
|
||||
}
|
||||
|
||||
class WithDBRefWrapper {
|
||||
|
||||
WithDBRef withDbRef;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -0,0 +1,66 @@
|
||||
/*
|
||||
* 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.index;
|
||||
|
||||
import static org.hamcrest.Matchers.*;
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.hamcrest.Matchers;
|
||||
import org.junit.After;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Qualifier;
|
||||
import org.springframework.data.mongodb.core.MongoOperations;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
|
||||
/**
|
||||
* Integration tests for {@link MongoPersistentEntityIndexCreator}.
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
@ContextConfiguration
|
||||
public class MongoPersistentEntityIndexCreatorIntegrationTests {
|
||||
|
||||
@Autowired
|
||||
@Qualifier("mongo1")
|
||||
MongoOperations templateOne;
|
||||
|
||||
@Autowired
|
||||
@Qualifier("mongo2")
|
||||
MongoOperations templateTwo;
|
||||
|
||||
@After
|
||||
public void cleanUp() {
|
||||
templateOne.dropCollection(SampleEntity.class);
|
||||
templateTwo.dropCollection(SampleEntity.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void createsIndexForConfiguredMappingContextOnly() {
|
||||
|
||||
List<IndexInfo> indexInfo = templateOne.indexOps(SampleEntity.class).getIndexInfo();
|
||||
assertThat(indexInfo, hasSize(greaterThan(0)));
|
||||
assertThat(indexInfo, Matchers.<IndexInfo> hasItem(hasProperty("name", is("prop"))));
|
||||
|
||||
indexInfo = templateTwo.indexOps("sampleEntity").getIndexInfo();
|
||||
assertThat(indexInfo, hasSize(0));
|
||||
}
|
||||
}
|
||||
@@ -24,9 +24,13 @@ import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.runners.MockitoJUnitRunner;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.data.mapping.context.MappingContextEvent;
|
||||
import org.springframework.data.mongodb.MongoDbFactory;
|
||||
import org.springframework.data.mongodb.core.mapping.Field;
|
||||
import org.springframework.data.mongodb.core.mapping.MongoMappingContext;
|
||||
import org.springframework.data.mongodb.core.mapping.MongoPersistentEntity;
|
||||
import org.springframework.data.mongodb.core.mapping.MongoPersistentProperty;
|
||||
|
||||
import com.mongodb.DBObject;
|
||||
|
||||
@@ -40,6 +44,8 @@ public class MongoPersistentEntityIndexCreatorUnitTests {
|
||||
|
||||
@Mock
|
||||
MongoDbFactory factory;
|
||||
@Mock
|
||||
ApplicationContext context;
|
||||
|
||||
@Test
|
||||
public void buildsIndexDefinitionUsingFieldName() {
|
||||
@@ -55,6 +61,40 @@ public class MongoPersistentEntityIndexCreatorUnitTests {
|
||||
assertThat(creator.name, is("indexName"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void doesNotCreateIndexForEntityComingFromDifferentMappingContext() {
|
||||
|
||||
MongoMappingContext mappingContext = new MongoMappingContext();
|
||||
|
||||
MongoMappingContext personMappingContext = new MongoMappingContext();
|
||||
personMappingContext.setInitialEntitySet(Collections.singleton(Person.class));
|
||||
personMappingContext.initialize();
|
||||
|
||||
DummyMongoPersistentEntityIndexCreator creator = new DummyMongoPersistentEntityIndexCreator(mappingContext, factory);
|
||||
|
||||
MongoPersistentEntity<?> entity = personMappingContext.getPersistentEntity(Person.class);
|
||||
MappingContextEvent<MongoPersistentEntity<?>, MongoPersistentProperty> event = new MappingContextEvent<MongoPersistentEntity<?>, MongoPersistentProperty>(
|
||||
personMappingContext, entity);
|
||||
|
||||
creator.onApplicationEvent(event);
|
||||
|
||||
assertThat(creator.indexDefinition, is(nullValue()));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATAMONGO-530
|
||||
*/
|
||||
@Test
|
||||
public void isIndexCreatorForMappingContextHandedIntoConstructor() {
|
||||
|
||||
MongoMappingContext mappingContext = new MongoMappingContext();
|
||||
mappingContext.initialize();
|
||||
|
||||
MongoPersistentEntityIndexCreator creator = new DummyMongoPersistentEntityIndexCreator(mappingContext, factory);
|
||||
assertThat(creator.isIndexCreatorFor(mappingContext), is(true));
|
||||
assertThat(creator.isIndexCreatorFor(new MongoMappingContext()), is(false));
|
||||
}
|
||||
|
||||
static class Person {
|
||||
|
||||
@Indexed(name = "indexName")
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
package org.springframework.data.mongodb.core.index;
|
||||
|
||||
import org.springframework.data.annotation.Id;
|
||||
import org.springframework.data.mongodb.core.mapping.Document;
|
||||
|
||||
@Document
|
||||
public class SampleEntity {
|
||||
|
||||
@Id
|
||||
String id;
|
||||
|
||||
@Indexed
|
||||
String prop;
|
||||
}
|
||||
@@ -68,6 +68,16 @@ public class BasicMongoPersistentPropertyUnitTests {
|
||||
getPropertyFor(ReflectionUtils.findField(Person.class, "ssn"));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATAMONGO-553
|
||||
*/
|
||||
@Test
|
||||
public void usesPropertyAccessForThrowableCause() {
|
||||
|
||||
MongoPersistentProperty property = getPropertyFor(ReflectionUtils.findField(Throwable.class, "cause"));
|
||||
assertThat(property.usePropertyAccess(), is(true));
|
||||
}
|
||||
|
||||
private MongoPersistentProperty getPropertyFor(Field field) {
|
||||
return new BasicMongoPersistentProperty(field, null, entity, new SimpleTypeHolder());
|
||||
}
|
||||
|
||||
@@ -16,20 +16,36 @@
|
||||
|
||||
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.Collections;
|
||||
import java.util.Map;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.runners.MockitoJUnitRunner;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.data.annotation.Id;
|
||||
import org.springframework.data.mapping.context.AbstractMappingContext;
|
||||
import org.springframework.data.mapping.model.MappingException;
|
||||
import org.springframework.util.ReflectionUtils;
|
||||
|
||||
import com.mongodb.DBRef;
|
||||
|
||||
/**
|
||||
* Unit tests for {@link MongoMappingContext}.
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
@RunWith(MockitoJUnitRunner.class)
|
||||
public class MongoMappingContextUnitTests {
|
||||
|
||||
@Mock
|
||||
ApplicationContext applicationContext;
|
||||
|
||||
@Test
|
||||
public void addsSelfReferencingPersistentEntityCorrectly() throws Exception {
|
||||
|
||||
@@ -46,6 +62,24 @@ public class MongoMappingContextUnitTests {
|
||||
context.getPersistentEntity(ClassWithMultipleIdProperties.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void doesNotReturnPersistentEntityForMongoSimpleType() {
|
||||
|
||||
MongoMappingContext context = new MongoMappingContext();
|
||||
assertThat(context.getPersistentEntity(DBRef.class), is(nullValue()));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void populatesAbstractMappingContextsApplicationCorrectly() {
|
||||
|
||||
MongoMappingContext context = new MongoMappingContext();
|
||||
context.setApplicationContext(applicationContext);
|
||||
|
||||
Field field = ReflectionUtils.findField(AbstractMappingContext.class, "applicationContext");
|
||||
ReflectionUtils.makeAccessible(field);
|
||||
assertThat(ReflectionUtils.getField(field, context), is(notNullValue()));
|
||||
}
|
||||
|
||||
class ClassWithMultipleIdProperties {
|
||||
|
||||
@Id
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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.
|
||||
@@ -44,11 +44,9 @@ import com.mongodb.Mongo;
|
||||
@ContextConfiguration("classpath:infrastructure.xml")
|
||||
public class GroupByTests {
|
||||
|
||||
@Autowired
|
||||
MongoDbFactory factory;
|
||||
@Autowired MongoDbFactory factory;
|
||||
|
||||
@Autowired
|
||||
ApplicationContext applicationContext;
|
||||
@Autowired ApplicationContext applicationContext;
|
||||
|
||||
MongoTemplate mongoTemplate;
|
||||
|
||||
@@ -158,7 +156,7 @@ public class GroupByTests {
|
||||
|
||||
private void assertMapReduceResults(GroupByResults<XObject> results) {
|
||||
DBObject dboRawResults = results.getRawResults();
|
||||
String expected = "{ \"serverUsed\" : \"127.0.0.1:27017\" , \"retval\" : [ { \"x\" : 1.0 , \"count\" : 2.0} , { \"x\" : 2.0 , \"count\" : 1.0} , { \"x\" : 3.0 , \"count\" : 3.0}] , \"count\" : 6.0 , \"keys\" : 3 , \"ok\" : 1.0}";
|
||||
String expected = "{ \"serverUsed\" : \"/127.0.0.1:27017\" , \"retval\" : [ { \"x\" : 1.0 , \"count\" : 2.0} , { \"x\" : 2.0 , \"count\" : 1.0} , { \"x\" : 3.0 , \"count\" : 3.0}] , \"count\" : 6.0 , \"keys\" : 3 , \"ok\" : 1.0}";
|
||||
Assert.assertEquals(expected, dboRawResults.toString());
|
||||
|
||||
int numResults = 0;
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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.
|
||||
@@ -15,11 +15,12 @@
|
||||
*/
|
||||
package org.springframework.data.mongodb.core.query;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
import static org.hamcrest.CoreMatchers.*;
|
||||
import static org.junit.Assert.*;
|
||||
import static org.springframework.data.mongodb.core.query.Criteria.*;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.springframework.data.domain.Sort.Direction;
|
||||
|
||||
import com.mongodb.BasicDBObject;
|
||||
import com.mongodb.DBObject;
|
||||
@@ -51,7 +52,7 @@ public class BasicQueryUnitTests {
|
||||
|
||||
BasicQuery query = new BasicQuery("{}");
|
||||
query.setSortObject(new BasicDBObject("name", -1));
|
||||
query.sort().on("lastname", Order.ASCENDING);
|
||||
query.with(new org.springframework.data.domain.Sort(Direction.ASC, "lastname"));
|
||||
|
||||
DBObject sortReference = new BasicDBObject("name", -1);
|
||||
sortReference.put("lastname", 1);
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user