1

I have an entity class:

@Document(collection = "messages")
public class Message {
    @Id
    private String id;
}

And I'm using QueryDsl for generating Mongo queries. Querydsl generates necessary QMessage class:

@Generated("com.querydsl.codegen.EntitySerializer")
public class QMessage extends EntityPathBase<Message> {
    private static final PathInits INITS = PathInits.DIRECT2;

    public static final QMessage message = new QMessage("message");

    public final StringPath id = createString("id");
}

with id field as a StringPath. Then I'm trying to query messages by id using predicate with:

QMessage message = QMessage.message;
BooleanExpression predicate = message.id.goe("someId").and(message.id.loe("someId"));

and use findAll(predicate) method in QuerydslPredicateExecutor. And it does create a correct query:

find "messages", filter { $and: [ { _id: { $gte: "someId" } }, { _id: { $lte: "someId" } } ] }

But the problem is that mongo cannot find anything if you query by id as a String. Because when inserting this document, mongo creates an ObjectId on this field, so the correct query would be:

find "messages", filter { $and: [ { _id: { $gte: ObjectId('someId') } }, { _id: { $lte: ObjectId('someId') } } ] }

So I've come up with manual creation of necessary path like this:

Path<Message> message = Expressions.path(Message.class, "message");
Path<ObjectId> idField = Expressions.path(ObjectId.class, message, "id");
Constant<ObjectId> objectIdGT = (Constant<ObjectId>) Expressions.constant(new ObjectId("someId"));
Constant<ObjectId> objectIdLT = (Constant<ObjectId>) Expressions.constant(new ObjectId("someId"));
BooleanExpression predicate = Expressions.predicate(Ops.GOE, idField, objectIdGT).and(Expressions.predicate(Ops.LOE, idField, objectIdLT));

And it works, but I would like to have this path generated automatically by QueryDsl with all other paths. Is there any annotation\configuration to customize code generation?

Kristina
  • 55
  • 5
  • 1
    I don't think the path expressions make any difference here. They still produce the exact same search expression. The actual trick needed to get this to work, is what you did to the constants (wrapping them in ObjectId). So how exactly would a change in the metamodel code generation make this easier? – Jan-Willem Gmelig Meyling Aug 27 '20 at 15:38
  • 1
    But basically you want any `String` property annotated with `@Id` to map to a `ComparablePath` rather than a `StringPath` in the metamodel class, correct? – Jan-Willem Gmelig Meyling Aug 27 '20 at 15:40
  • Yes, you're both right, path initialization was redundant and yes, would be great if I could change the field type somehow so that I would just use path.goe method instead of Constants and Expressions.predicate But I guess there's no way to do something like this at the moment – Kristina Aug 28 '20 at 12:36
  • 1
    Why don't you just use `ObjectId` as type for the field in the entity? Thats at least what we seem to do in the test suite: https://github.com/querydsl/querydsl/blob/2bf234caf78549813a1e0f44d9c30ecc5ef734e3/querydsl-mongodb/src/test/java/com/querydsl/mongodb/domain/AbstractEntity.java – Jan-Willem Gmelig Meyling Aug 28 '20 at 12:58

0 Answers0