mongodbspring-dataquerydsl

QueryDslMongoRepository Projection


I am using spring-data for mongodb with querydsl. I have a repository

public interface DocumentRepository extends MongoRepository<Document, String> ,QueryDslPredicateExecutor<Document> {}

and an entity

@QueryEntity
public class Document {

private String id;
private String name;
private String description;
private boolean locked;
private String message;

}

I need to load a list of documents with id and name informations. So only id and name should be loaded and set in my entity. I think query projection is the right word for it. Is this supported?

In addition I need to implement some lazy loading logic. Is there anything like "skip" and "limit" features in a repository?


Solution

  • According to the Answer of this -> Question <- I implemeted following solution.

    Entity

    @QueryEntity
    public class Document extends AbstractObject {
    }
    

    Custom QuerydslMongoRepository

    public interface CustomQuerydslMongoRepository<T extends AbstractObject,ID extends Serializable> extends MongoRepository<T, ID> ,QueryDslPredicateExecutor<T>{
        Page<T> findAll(Predicate predicate, Pageable pageable,Path... paths);
        Page<T> findAll(Predicate predicate, Pageable pageable,List<Path> projections);
    
    }
    

    Custom QuerydslMongoRepository Implementation

    public class CustomQuerydslMongoRepositoryImpl<T extends AbstractObject,ID extends Serializable> extends QueryDslMongoRepository<T,ID> implements CustomQuerydslMongoRepository<T,ID> {
    
        //All instance variables are available in super, but they are private
        private static final EntityPathResolver DEFAULT_ENTITY_PATH_RESOLVER = SimpleEntityPathResolver.INSTANCE;
    
    
        private final EntityPath<T> path;
        private final PathBuilder<T> pathBuilder;
        private final MongoOperations mongoOperations;
        public CustomQuerydslMongoRepositoryImpl(MongoEntityInformation<T, ID> entityInformation, MongoOperations mongoOperations) {
            this(entityInformation, mongoOperations,DEFAULT_ENTITY_PATH_RESOLVER);
        }
    
        public CustomQuerydslMongoRepositoryImpl(MongoEntityInformation<T, ID> entityInformation, MongoOperations mongoOperations, EntityPathResolver resolver) {
            super(entityInformation, mongoOperations, resolver);
            this.path=resolver.createPath(entityInformation.getJavaType());
            this.pathBuilder = new PathBuilder<T>(path.getType(), path.getMetadata());
            this.mongoOperations=mongoOperations;
        }
    
        @Override
        public Page<T> findAll( Predicate predicate, Pageable pageable,Path... paths) {
            Class<T> domainType = getEntityInformation().getJavaType();
            MongodbQuery<T> query = new SpringDataMongodbQuery<T>(mongoOperations, domainType);
            long total = query.count();
            List<T> content = total > pageable.getOffset() ? query.where(predicate).list(paths) : Collections.<T>emptyList();
            return new PageImpl<T>(content, pageable, total);
        }
    
        @Override
        public Page<T> findAll(Predicate predicate, Pageable pageable, List<Path> projections) {
            Class<T> domainType = getEntityInformation().getJavaType();
            MongodbQuery<T> query = new SpringDataMongodbQuery<T>(mongoOperations, domainType);
            long total = query.count();
            List<T> content = total > pageable.getOffset() ? query.where(predicate).list(projections.toArray(new Path[0])) : Collections.<T>emptyList();
            return new PageImpl<T>(content, pageable, total);
        }
    }
    

    Custom Repository Factory

    public class CustomQueryDslMongodbRepositoryFactoryBean<R extends QueryDslMongoRepository<T, I>, T, I extends Serializable> extends MongoRepositoryFactoryBean<R, T, I> {
    
    
        @Override
        protected RepositoryFactorySupport getFactoryInstance(MongoOperations operations) {
            return new CustomQueryDslMongodbRepositoryFactory<T,I>(operations);
        }
    
        public static class CustomQueryDslMongodbRepositoryFactory<T, I extends Serializable> extends MongoRepositoryFactory {
            private MongoOperations operations;
    
            public CustomQueryDslMongodbRepositoryFactory(MongoOperations mongoOperations) {
                super(mongoOperations);
                this.operations = mongoOperations;
            }
    
    
            @SuppressWarnings({ "rawtypes", "unchecked" })
            protected Object getTargetRepository(RepositoryMetadata metadata) {
                    return new CustomQuerydslMongoRepositoryImpl(getEntityInformation(metadata.getDomainType()), operations);
              }
    
            protected Class<?> getRepositoryBaseClass(RepositoryMetadata metadata) {
                return CustomQuerydslMongoRepository.class;
            }
        }
    }
    

    Entity Repository

    public interface DocumentRepository extends CustomQuerydslMongoRepository<Document, String>{
    
    }
    

    Usage in Service

    @Autowired
    DocumentRepository repository;
    
    public List<Document> getAllDocumentsForListing(){
    return repository.findAll(  QDocument.document.id.isNotEmpty().and(QDocument.document.version.isNotNull()), new PageRequest(0, 10),QDocument.document.name,QDocument.document.version).getContent();
    }