spring-projects / spring-data-mongodb

Provides support to increase developer productivity in Java when using MongoDB. Uses familiar Spring concepts such as a template classes for core API usage and lightweight repository style data access.
https://spring.io/projects/spring-data-mongodb/
Apache License 2.0
1.62k stars 1.09k forks source link

MongoQueryCreator will not create query correctly when passing Pattern Object with options [DATAMONGO-2003] #2871

Closed spring-projects-issues closed 6 years ago

spring-projects-issues commented 6 years ago

Rizwan Ishtiaq opened DATAMONGO-2003 and commented

 

Problem

Query created from repository method name convention will not contain the options when passing Pattern object as method parameter

//Following regex we are trying to pass
Pattern regex = Pattern.compile("\\bpattern\\b",Pattern.CASE_INSENSITIVE);

//Following method in repository interface
List<Person> findByFirstNameRegex(Pattern regex);

Prove of problem

// new unit test in org.springframework.data.mongodb.repository.query.MongoQueryCreatorUnitTests

//This test will pass with current implementation
@Test 
public void createsRegexQueryCorrectlyWhenPassingPatternObject() throws Exception {

   final Pattern regex = Pattern.compile("\\bpattern\\b");
   PartTree tree = new PartTree("findByFirstNameRegex", Person.class);
   MongoQueryCreator creator = new MongoQueryCreator(tree, getAccessor(converter, regex), context);

   assertThat(creator.createQuery(), is(query(where("firstName").regex("\\bpattern\\b"))));
}

//Below test will fail with current implementation
@Test
public void createsRegexQueryCorrectlyWhenPassingPatternObjectWithOptions() throws Exception {

   final Pattern regex = Pattern.compile("\\bpattern\\b",Pattern.CASE_INSENSITIVE|Pattern.UNICODE_CASE);
   PartTree tree = new PartTree("findByFirstNameRegex", Person.class);
   MongoQueryCreator creator = new MongoQueryCreator(tree, getAccessor(converter, regex), context);
   assertThat(creator.createQuery(), is(query(where("firstName").regex("\\bpattern\\b","iu"))));
}

Note: above unit test will assume we have fixed the bug #DATAMONGO-2002

Reason

// in org.springframework.data.mongodb.repository.query.MongoQueryCreator

//Old implementation
private Criteria from(Part part, MongoPersistentProperty property, Criteria criteria, Iterator<Object> parameters) {
...
case REGEX:
   return criteria.regex(parameters.next().toString());
...
}

Solution

// in org.springframework.data.mongodb.repository.query.MongoQueryCreator

//New implementation
private Criteria from(Part part, MongoPersistentProperty property, Criteria criteria, Iterator<Object> parameters) {
...
case REGEX: 
Object param = parameters.next();
return param instanceof Pattern ? criteria.regex((Pattern) param) : criteria.regex(param.toString());
...
}

 


Affects: 1.10.12 (Ingalls SR12), 2.0.7 (Kay SR7), 2.1 M3 (Lovelace)

Issue Links:

Referenced from: pull request https://github.com/spring-projects/spring-data-mongodb/pull/570

Backported to: 2.0.8 (Kay SR8), 1.10.13 (Ingalls SR13)

spring-projects-issues commented 6 years ago

Rizwan Ishtiaq commented

Hi team, do you need me to fix it and create pull request?

spring-projects-issues commented 6 years ago

Christoph Strobl commented

Thanks Rizwan Ishtiaq. Pull requests (preferably with tests) are always welcome, but there's no need for you to craft one. If you've got time to do it, please make sure to follow the contribution guidelines and let us know. If not, that's fine - we've already added the issue to the current iteration and someone is likely to pick it up

spring-projects-issues commented 6 years ago

Rizwan Ishtiaq commented

Hi Christoph, thanks for responding, hope you noticed solution (with test cases) is already in description. If someone can fix it and commit it i will be happy with that. So that i can use snapshot in my project. I don't want to use @Query on my methods. So it is kind of show stopper for me. That why i asked for pull request if developers are busy. But hope it won't take much time

spring-projects-issues commented 6 years ago

Rizwan Ishtiaq commented

Christoph, where from i can get the maven dependency for this snapshot release?

spring-projects-issues commented 6 years ago

Christoph Strobl commented

you can obtain it via https://repo.spring.io/

spring-projects-issues commented 6 years ago

Rizwan Ishtiaq commented

Sorry, but i never used snapshot dependency in conjunction with spring boot.

I have tried it by replacing in pom file. Till 2.0.8.BUILD-SNAPSHOT work fine.

But after above version, not working. when i try to use 2.1.0.DATAMONGO-2003-SNAPSHOT its throwing Failed to introspect Class [org.springframework.data.mongodb.core.SimpleMongoDbFactory] from ClassLoader

Any hint from your side will be highly appreciable 

spring-projects-issues commented 6 years ago

Mark Paluch commented

Thanks a lot for trying this out. Version 2.0.8 will be released this week.

Spring Data MongoDB 2.1.0 adapted some changes from Spring Data Commons 2.1.0 which require updating both, MongoDB and Commons to a 2.1.0 snapshot artifact.

 

spring-projects-issues commented 6 years ago

Rizwan Ishtiaq commented

Sorry again. I tried but failed. Below is a part of my pom file 

 

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-mongodb</artifactId>
</dependency>

<dependency>
    <groupId>org.springframework.data</groupId>
    <artifactId>spring-data-mongodb</artifactId>
    <version>2.1.0.DATAMONGO-2003-SNAPSHOT</version>
</dependency>

<dependency>
    <groupId>org.springframework.data</groupId>
    <artifactId>spring-data-commons</artifactId>
    <version>2.1.0.BUILD-SNAPSHOT</version>
</dependency>

But still getting exception. Below is the part of stack trace

 

 

Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'mongoDbFactory' defined in class path resource [org/springframework/boot/autoconfigure/data/mongo/MongoDataAutoConfiguration.class]

Caused by: java.lang.IllegalStateException: Failed to introspect Class [org.springframework.data.mongodb.core.SimpleMongoDbFactory]

Caused by: java.lang.NoClassDefFoundError: com/mongodb/client/ClientSession

Caused by: java.lang.ClassNotFoundException: com.mongodb.client.ClientSession

 

 

spring-projects-issues commented 6 years ago

Christoph Strobl commented

2.1.0.BUILD-SNAPSHOT s require mongo-java-driver:3.8.0-beta3

spring-projects-issues commented 6 years ago

Mark Paluch commented

Thanks a lot. I missed that one entirely. We're supporting with version 2.1 client sessions and transactions which requires a driver upgrade. Care to upgrade to MongoDB driver 3.8.0-beta2 (and when using the reactive driver also to MongoDB Reactive Streams Driver 1.9.0-beta1)?

By the way, you can also use 2.1.0.BUILD-SNAPSHOT for Spring Data MongoDB since the fix is already merged to master

spring-projects-issues commented 6 years ago

Rizwan Ishtiaq commented

Thank you guys, that helped a lot. Both drivers 3.8.0-beta2 and 3.8.0-beta3 working fine. I am able to start application with following

//Dependencies in pom file
org.springframework.data:spring-data-mongodb:2.1.0.BUILD-SNAPSHOT
org.springframework.data:spring-data-commons:2.1.0.BUILD-SNAPSHOT

// Property in pom file
<mongodb.version>3.8.0-beta3</mongodb.version>

Bug is also fixed