15

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?

codependent
  • 23,193
  • 31
  • 166
  • 308

2 Answers2

6

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
}
codependent
  • 23,193
  • 31
  • 166
  • 308
4

try this;

Query que = new Query();
que.addCriteria(Criteria.where("user.$id").is(new ObjectId("123456789012345678901234")));
skypjack
  • 49,335
  • 19
  • 95
  • 187
  • 1
    This doesn't works in my case. Will you guide me here https://stackoverflow.com/questions/55401324/dbref-doesnt-pull-the-data-when-use-spring-data-mongo – PAA Mar 28 '19 at 16:17
  • This does not work for me as well. I am using Spring Boot 2.1.6, spring-data-mongod 2.1.9 Spring seems to turn the ObjectId to `$oid`, e.g. `{"user.$id":{"$oid":"123456789012345678901234"}}` – Amnon Mar 28 '23 at 16:12