Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Spring Data Mongo - How to query by @DBRef field's id

I am new to Spring Data Mongo so I must be doing something wrong because I can't manage to execute such a simple query. This is my model:

@Document(collection="brands")
public class Brand{
    @Id
    private int id;

    private String name;
    ...
    //getters-setters
}

@Document(collection="models")
public class Model{
    @Id
    private int id;
    private String name;
    @DBRef
    private Brand brand;
    ...
    //getters-setters
}

I would like to get all models from a brand, so I implement the DAO as follows:

@Repository
public interface IModelDAO extends MongoRepository<Model, Integer>{
    @Query(value="{ 'brand.$id' : ?0 }")
    public List<Model> findByBrandId(Integer id);   
}

If I execute this mongodb query in the shell it works: db.modelss.find({ 'brand.$id' : 1 })

But, the Java application throws the following exception:

Caused by: java.lang.IllegalAccessError
at org.springframework.data.mapping.PropertyReferenceException.detectPotentialMatches(PropertyReferenceException.java:134)

Apparently it is looking for a field $id in Brand class, and since it doesn't exist it fails. So I change the query to the following, so that it navigates to the id field:

@Query(value="{ 'brand.id' : ?0 }")

Now, it doesn't throw an exception but it doesn't find anything in the DB.

Debugging the MongoTemplate.executeFindMultiInternal() method in can see that in

DBCursor cursor = null;
    try {
        cursor = collectionCallback.doInCollection(getAndPrepareCollection(getDb(), collectionName));

cursor's query is query={ "brand" : 134}. So it makes sense it doesn't find anything. Changing the query value during debugging to query={ "brand.$id" : 134} it works.

So, why isn't the query correctly translated?

like image 902
codependent Avatar asked Oct 19 '15 10:10

codependent


People also ask

What is @DBRef in MongoDB?

DBRefs are references from one document to another using the value of the first document's _id field, collection name, and, optionally, its database name, as well as any other fields. DBRefs allow you to more easily reference documents stored in multiple collections or databases.

How MongoDB read data in spring boot?

Read operations using Spring Boot MongoDBFetch all the documents (grocery items) using the findAll() method. Get a single item (document) by its name field using the findItemByName method. Get a list of items based on a category.

What is @DBRef lazy true?

I am using @DBRef(lazy=true) so that I do not load the college associated with the student. For example: if I have a repository method for Student called findByFirstname(String firstname), I can load the student without the college. However, at times I would also want to load the student with college.

Which fields are in DBRefs?

DBRefs are made up of three fields: $ref: This field specifies the collection of the referenced document. $id: This field specifies the _id field of the referenced document. $db: This is an optional field and contains the name of the database in which the referenced document lies.


2 Answers

The problem was caused by the @Id int type. Changing it to Integer solved it:

@Document(collection="brands")
public class Brand{
    @Id
    private Integer id;

    private String name;
    ...
    //getters-setters
}

@Document(collection="models")
public class Model{
    @Id
    private Integer id;
    private String name;
    @DBRef
    private Brand brand;
    ...
    //getters-setters
}
like image 90
codependent Avatar answered Oct 05 '22 13:10

codependent


try this;

Query que = new Query();
que.addCriteria(Criteria.where("user.$id").is(new ObjectId("123456789012345678901234")));
like image 22
Mohammad Badiuzzaman Avatar answered Oct 05 '22 13:10

Mohammad Badiuzzaman