Skip to content

Querydsl predicate using IN operator fails for DBRef [DATAMONGO-1810] #2716

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
spring-projects-issues opened this issue Oct 23, 2017 · 8 comments
Assignees
Labels
type: bug A general bug

Comments

@spring-projects-issues
Copy link

Luis Miguel Ospina opened DATAMONGO-1810 and commented

Suppose i have these classes.

@Document
Obj1 {
  @DbRef Obj2 obj2;
}
 
Obj2 {
  @Id
  String id;
}

When i try to create a querydsl predicate all the Obj1 that matches the id of Obj2 it works fine if i search for only one Id (use the eq operation in the SimpleExpression queryDsl class), something like this.
Predicate predicate = QObj1.Obj1.Obj2.id.eq("ID123");
That will work perfect when i call the findAll(predicate) method.

But when ever i try to use the IN operator, looking for a bunch of Id's it will not work, something like this:

Predicate predicate = QObj1.Obj1.Obj2.id.in(Arrays.asList("ID123","ID1234"));
And try to call the findAll(predicate), that will not work at all, it returns no data, even if there's data that matches those ID's in the MongoDB.


Issue Links:

  • DATAMONGO-1848 Migrate to Document API-based Querydsl implementation
    ("depends on")

  • DATAMONGO-2010 SpringDataMongodbSerializer does not convert 'in' predicate for nested String id properties mapping to ObjectId

  • DATAMONGO-1394 References not handled correctly when using QueryDSL

@spring-projects-issues
Copy link
Author

Luis Miguel Ospina commented

Digging a little bit into QueryDsl i found that when you use the:

Predicate predicate = QObj1.Obj1.Obj2.id.eq("ID123");

The result query will be something like:

{ "obj2" : { "$ref" : "Obj2", "$id" : "ID123"} }

But when you use the:

Predicate predicate = QObj1.Obj1.Obj2.id.in(Arrays.asList("ID123","ID1234"));

The result query will look like this:

{ "obj2" : { "$in" :  ["ID123" , "ID1234"] } }  

the previous query doesn't work even if i use MongoDB directly. however it'll work if you change the query to this.

{ "obj2.$id" : { "$in" :  ["ID123" , "ID1234"] } }  

@spring-projects-issues
Copy link
Author

Christoph Strobl commented

Luis Miguel Ospina which version of Spring Data MongoDB are you using? I've tried to set up a testcase for the issue which passes just fine

@spring-projects-issues
Copy link
Author

Luis Miguel Ospina commented

@Christoph Strobl i'm using Spring boot 1.5.7.RELEASE (including the MongoDB Dependency, spring-data-mongodb-1.10.7.RELEASE )

Can you post the test case here?
when ever i have the chance i'll push a small project to GitHub with the corresponding test cases failing

@spring-projects-issues
Copy link
Author

Luis Miguel Ospina commented

@Christoph there you go https://github.com/luismospinam/Spring-data-mongoDB-1810/
Simple spring boot project, the second test case (which use the "IN") is failing.

Let me know if you need anything else

@spring-projects-issues
Copy link
Author

Christoph Strobl commented

thanks Luis Miguel Ospina! I see, seems Querydsl converts in clauses for single elemented list to eq, having add a second element made the test fail

@spring-projects-issues
Copy link
Author

Christoph Strobl commented

After a bit of investigation it seems likely that the issue cannot be solved entirely without requireing changes in Querydsl itself. I came accross Issue #2133 which currently prevents values used for $in, $nin from being converted prior to their usage.

This means, that we could make it work for id properties that do not require any additional conversion, such as Integer, Long, ObjectId even String values that do not map to valid ObjectId s.

Still without changes in Querydsl the following would still fail, as on save the entity is stored in MongoDB with an id of type ObjectId and when mapping the query, this information is lost, so that the given values do not get converted. So the String type obviously do not match to the ObjectId in the store.

User bart = new User();
bart.setUsername("[email protected]");

User lisa = new User();
lisa.setUsername("[email protected]");

operations.save(bart);
operations.save(lisa);

Person milhouse = new Person();
milhouse.setCoworker(bart);

operations.save(milhouse);

Person result = repoSupport.from(QPerson.person)
	.where(QPerson.person.coworker.id.in(Arrays.asList(bart.getId(), lisa.getId())))
        .fetchOne();

@spring-projects-issues
Copy link
Author

Luis Miguel Ospina commented

Thank you so much Christoph, lets wait for an answer from the Querydsl team.
I'll check if the solution you made on the SpringDataMongodbSerializer class will work in my case while the Querydsl resolve the main problem

@spring-projects-issues
Copy link
Author

Christoph Strobl commented

Resolved via DATAMONGO-1848

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
type: bug A general bug
Projects
None yet
Development

No branches or pull requests

2 participants