Morphia Query by Reference ObjectID

6.8k Views Asked by At

Here's my entity's definition:

@Entity("Comment")
public class Comment extends BaseEntity {

    @Reference
    private Merchant merchant;

    ...
}

@Entity("Merchant")
class Merchant extends BaseEntity{
    @Id
    @Property("id")
    protected ObjectId id;

    ...
}

And here's my data:

comment:{
"_id": ObjectId("546c1ac64652e5180dc21577"),
"merchant" : DBRef("Merchant", ObjectId("546c1ac64652e5180dc21576")),

...
}

When I create a Query like:

Query<Comment> query = ds.createQuery(Comment.class);
query.field("merchant").equal(new ObjectId("546c1ac64652e5180dc21576"));

commentDao.findOne(query);

There's no result returned, I'd like to ask which is the right way to query a comment data with merchant's ObjectId?

Thanks for your help.

4

There are 4 best solutions below

2
On BEST ANSWER
Query<Comment> query = ds.find(Comment.class).disableValidation()
    .field("Merchant").equal(new Key<>(Merchant.class, merchantId);

I think you need to disable validation, otherwise you'll see some rather unnecessary warning.

You can query the DBRef ID directly, but since DBRef itself is typed, I'd not circumvent it unless you have some valid reason.

0
On

I don't like the way that Morphia uses DBRef when it could easily use just ObjectId (but the DBRef does contain the class name allowing you to subclass Merchant).

Anyway, you should be able to do:

Query<Comment> query = ds.createQuery(Comment.class);
query.field("merchant.$id").equal(new ObjectId("546c1ac64652e5180dc21576")

or with pure Java driver

collection.find(new BasicDBObject("merchant",
    new BasicDBObject("$ref", "Merchant")
      .append("$id", new ObjectId("546c1ac64652e5180dc21576"))))
0
On

The correct way is to get the Merchant object with the ID, and then pass it to the Comment query:

Query<Merchant> merchantQuery = ds.createQuery(Merchant.class);
merchantQuery.field("id").equal(new ObjectId(merchantId)); 
Merchant merchant = merchantQuery.get();     // Get the Merchant object

Query<Comment> commentQuery = ds.createQuery(Comment.class);
commentQuery.filter("merchant", merchant);
commentQuery.get()                           // Get the Comment object
0
On

You can do with mongodb driver

        MongoClient mongo =new MongoClient(mongoURI);
        DBCollection dbCollection =mongo.getDB("<your_db>").getCollection("Comment");
        DBObject dbObject = (DBObject) JSON.parse("{ 'merchant' : { '$ref' : 'Merchant' , '$id' : { '$oid' : '5693e72244ae9fe4803a4520'}}}");

        String json=JSON.serialize(dbCollection.find(dbObject));

Note the single qoute in the json.

OR

In Morphia like:

Query q = MorphiaObject.datastore.find(Comment.class).field("merchant").equal(MorphiaObject.datastore.get(Merchant.class,new ObjectId("5693e72244ae9fe4803a4520")));