Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Spring Data MongoDB Repository - JPA Specifications like

Is there something like JPA Specifications for Spring Data MongoDB Repositories?

If not, how can I make dynamic queries with repositories?

A classic scenario could be a search form with optional fields that the user will fill.

like image 268
s1moner3d Avatar asked Nov 16 '15 12:11

s1moner3d


People also ask

What is Spring data JPA specification?

Spring Data JPA allows us to connect with different relational databases through a common interface to create JPA (Java Persistence API) based repositories. We can easily create database queries by using method names, the @Query annotation, and named queries to retrieve data from the database.

Is JPA a specification?

The Java Persistence API (JPA) is a Java specification for accessing, persisting, and managing data between Java objects / classes and a relational database. JPA was defined as part of the EJB 3.0 specification as a replacement for the EJB 2 CMP Entity Beans specification.

Is JPA and Spring data JPA same?

Spring data jpa- it is same like jpa means we can describe in below way. Spring Data Jpa is jpa data abstraction access which means it likes a jpa but it add some extra functionality, Without jpa we can not implement the spring data jpa.

Can I use Spring data JPA with MongoDB?

Yes, DataNucleus JPA allows it, as well as to many other databases.


2 Answers

I found myself a way.

The trick can be done using QueryDSL, in the following way:

First, add the QueryDSL dependencies:

<dependency>
    <groupId>com.mysema.querydsl</groupId>
    <artifactId>querydsl-mongodb</artifactId>
    <version>${querydsl-mongo.version}</version>
</dependency>

<dependency>
    <groupId>com.mysema.querydsl</groupId>
    <artifactId>querydsl-apt</artifactId>
    <version>${querydsl-mongo.version}</version>
</dependency>

Then, configure the plugin in order to create Metamodels classes (their names will be the same of the documents with the letter Q as prefix: eg. QUser):

    <build>
        <plugins>
            ....
            <plugin>
                <groupId>com.mysema.maven</groupId>
                <artifactId>apt-maven-plugin</artifactId>
                <version>1.1.3</version>
                <executions>
                    <execution>
                        <goals>
                            <goal>process</goal>
                        </goals>
                        <configuration>
                            <outputDirectory>target/generated-sources/java</outputDirectory>
                            <processor>org.springframework.data.mongodb.repository.support.MongoAnnotationProcessor</processor>
                        </configuration>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>

Note the processor class: it's not the QueryDSL default one com.mysema.query.apt.morphia.MorphiaAnnotationProcessor, but the Spring Data MongoDB one org.springframework.data.mongodb.repository.support.MongoAnnotationProcessor:

Spring Data Mongo provides a custom APT processor to generate the Metamodels instead of the one provided in QueryDSL, it will scan the Spring specific @Document instead of the Morphia specific annotations.

Now we can make our repository interface extending QueryDslPredicateExecutor<T>:

public interface UserRepository extends MongoRepository<User, String>, QueryDslPredicateExecutor<User>,
        QuerydslBinderCustomizer<QUser> {
}

We can now define Predicates when querying the repository:

QUser user = QUser.user;            
BooleanExpression predicate = user.name.containsIgnoreCase("John");         
userRepository.findAll(predicate);

QuerydslBinderCustomizer helps you to define the binding of the Document's properties (see Spring documentation for further help).

like image 109
s1moner3d Avatar answered Sep 23 '22 17:09

s1moner3d


This is update as of:

<spring.version>4.3.4.RELEASE</spring.version>
<querydsl.version>4.1.3</querydsl.version>
<spring.data.mongodb.version>1.9.5</spring.data.mongodb.version>

use

...
            <plugin>
            <groupId>com.mysema.maven</groupId>
            <artifactId>apt-maven-plugin</artifactId>
            <version>1.1.3</version>
            <executions>
                <execution>
                    <goals>
                        <goal>process</goal>
                    </goals>
                    <configuration>
                        <outputDirectory>target/generated-sources/java</outputDirectory>
                        <processor>org.springframework.data.mongodb.repository.support.MongoAnnotationProcessor</processor>
                    </configuration>
                </execution>
            </executions>
        </plugin>
...

    <dependency>
        <groupId>com.querydsl</groupId>
        <artifactId>querydsl-mongodb</artifactId>
        <version>${querydsl.version}</version>
    </dependency>

    <dependency>
        <groupId>com.querydsl</groupId>
        <artifactId>querydsl-apt</artifactId>
        <version>${querydsl.version}</version>
    </dependency>
like image 42
Slav Avatar answered Sep 21 '22 17:09

Slav