Announcement Announcement Module
Collapse
No announcement yet.
MongoDB repository queries for documents with DBRef attributes Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • MongoDB repository queries for documents with DBRef attributes

    Hi Team,

    Could you please give me a hint about using queries for documents with DBRef attributes? To be more specific, I have following classes:

    Code:
    @Document
    public class Type {
    
        @Id
        private ObjectId id;
    }
    
    @Document
    public class Entity {
    
        @Id
        private ObjectId id;
    
        @DBRef
        private Type type;
    
    
        public Entity(Type type) {
            this.type = type;
        }
    }
    
    public interface TypeRepository extends MongoRepository<Type, String> {
    }
    
    public interface EntityRepository extends MongoRepository<Entity, String> {
        List<Entity> findByType(Type p);
    }
    So, here I'm creating an instance of Entity and then trying to find it by given type. However, as soon as type attribute is stored in mongodb as a DBRef object, query fails.

    Code:
    public class Main {
    
        public static void main(String[] args) throws Exception {
            ConfigurableApplicationContext context = new ClassPathXmlApplicationContext("META-INF/beans.xml");
            MongoTemplate mongoTemplate = context.getBean(MongoTemplate.class);
            RepositoryFactorySupport repoFactory = new MongoRepositoryFactoryBean.MongoRepositoryFactory(mongoTemplate);
    
            EntityRepository entityRepository = repoFactory.getRepository(EntityRepository.class);
            TypeRepository typeRepository = repoFactory.getRepository(TypeRepository.class);
    
            entityRepository.deleteAll();
            typeRepository.deleteAll();
    
            Type t = new Type();
            typeRepository.save(t);
    
            Entity e = new Entity(t);
            entityRepository.save(e);
    
            System.out.println(entityRepository.findAll());
            System.out.println(entityRepository.findByType(t));
        }
    }
    As a result, call to findAll returns a single object (as expected), and call to findByType returns an empty collection.

    Am I doing anything wrong here?

    The best solution that I've found is to use custom query as follows:
    Code:
    public interface EntityRepository extends MongoRepository<Entity, String> {
    
        @Query("{ 'type': {'$ref': 'type', '$id': { '$oid': ?0 } } }")
        List<Entity> findByType(String typeIdAsString);
    }
    I guess it would be a nice improvement if query creator service would inspect if query criteria param is a DBRef in a document class and therefore should also be converted to DBRef object before putting to query.

    Thanks

  • #2
    I tried but it works only for "id" field. How should my query look like if i want to query for another field. I have an object:
    Freelancer {
    @Id
    String id;
    @DBRef
    List<Project> projects;
    }

    Project {
    @Id
    String id;
    String name;
    String title;
    }

    If i want to search based on title, i assume the query should look like:
    @Query("{ 'projects': {'$ref': 'project', '$title': { '$title' : ?0 } } }")

    This doesn't work.
    Originally posted by sskrobotov View Post
    Hi Team,

    Could you please give me a hint about using queries for documents with DBRef attributes? To be more specific, I have following classes:

    Code:
    @Document
    public class Type {
    
        @Id
        private ObjectId id;
    }
    
    @Document
    public class Entity {
    
        @Id
        private ObjectId id;
    
        @DBRef
        private Type type;
    
    
        public Entity(Type type) {
            this.type = type;
        }
    }
    
    public interface TypeRepository extends MongoRepository<Type, String> {
    }
    
    public interface EntityRepository extends MongoRepository<Entity, String> {
        List<Entity> findByType(Type p);
    }
    So, here I'm creating an instance of Entity and then trying to find it by given type. However, as soon as type attribute is stored in mongodb as a DBRef object, query fails.

    Code:
    public class Main {
    
        public static void main(String[] args) throws Exception {
            ConfigurableApplicationContext context = new ClassPathXmlApplicationContext("META-INF/beans.xml");
            MongoTemplate mongoTemplate = context.getBean(MongoTemplate.class);
            RepositoryFactorySupport repoFactory = new MongoRepositoryFactoryBean.MongoRepositoryFactory(mongoTemplate);
    
            EntityRepository entityRepository = repoFactory.getRepository(EntityRepository.class);
            TypeRepository typeRepository = repoFactory.getRepository(TypeRepository.class);
    
            entityRepository.deleteAll();
            typeRepository.deleteAll();
    
            Type t = new Type();
            typeRepository.save(t);
    
            Entity e = new Entity(t);
            entityRepository.save(e);
    
            System.out.println(entityRepository.findAll());
            System.out.println(entityRepository.findByType(t));
        }
    }
    As a result, call to findAll returns a single object (as expected), and call to findByType returns an empty collection.

    Am I doing anything wrong here?

    The best solution that I've found is to use custom query as follows:
    Code:
    public interface EntityRepository extends MongoRepository<Entity, String> {
    
        @Query("{ 'type': {'$ref': 'type', '$id': { '$oid': ?0 } } }")
        List<Entity> findByType(String typeIdAsString);
    }
    I guess it would be a nice improvement if query creator service would inspect if query criteria param is a DBRef in a document class and therefore should also be converted to DBRef object before putting to query.

    Thanks

    Comment


    • #3
      You have to do two queries:
      http://forum.springsource.org/showth...ocument-Fileds

      Comment

      Working...
      X