Question

I am trying to implement a QueryDslMongoRepository for a model "Document"

@QueryEntity
@Document(collection="currentDocuments")
public class DocumentImpl extends TranslatableObjectImpl implements Document

In our current implementation a to be deleted document moves von "currentDocuments" into "deletedDocuments" collection.

I cant find a solution to create a repository like this

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

with a dynamic collection name.

My goal is to have the advantages of queryDsl in one Repository for different collections and to be able to move models from one collection into another like

public move(DocumentImpl entity, String sourceCollection, String targetCollection){
    repository.delete(entity,sourceCollection);
    repository.save(entity,targetCollection);
}

or something like

public List<Document> findAllDocumentsWithAttachments(String collectionName){
    return repository.findAll(QDocumentImpl.documentImpl.attachments.isNotEmpty(), collectionName);
}

Any suggestions?

Was it helpful?

Solution 2

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>{
    List<T> findAll(Predicate predicate, String collectionName);
    T save(T entity, String collectionName);
    ...     
}

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 List<T> findAll(Predicate predicate, String collectionName) {

    MongodbQuery<T> query = createQueryFor(predicate,collectionName);
    return query.list();
}

    @Override
public T save(T entity,String collectionName){
    Assert.notNull(entity, "Entity must not be null!");
    mongoOperations.save(entity, collectionName);
    return entity;
}

    private MongodbQuery<T> createQueryFor(Predicate predicate,String collectionName) {
    Class<T> domainType = getEntityInformation().getJavaType();
    MongodbQuery<T> query = new SpringDataMongodbQuery<T>(getMongoOperations(), domainType,collectionName);
    return query.where(predicate);
}   
}

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> getAllDocuments(Predicate predicate){
return repository.findAll(predicate,"myCustomCollection");
}

OTHER TIPS

I implemented this feature by creating an own FactoryBean extending MongoRepositoryFactoryBean.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top