简体   繁体   中英

How to add default query criteria for all the queries when using method queries in spring boot mongodb

I have a requirement to execute method queries against a given mongo database and retrieve data. But for that, I have to check whether the field delete=false (Soft delete) for taking them for all the queries.

It can be achieved by the following kind of query

eg: Optional<User> findByIdAndDeletedIsFalse(String id);

But as you can see we have to put DeletedIsFalse for all the queries. I tried the answer provided in How to add default criteria to all the queries by default in mongo spring boot but I could find out that it can be only used then we are running queries directly using the mongo template.

After some debugging, I could find out that even though method queries are executed through the Mogno template, they are using package-protected classes and methods to do it. So they cannot be overridden by an inherited class. I cannot find an entry point for them to executed and where to inject default criteria for the method queries.

Eg: If we check the implementation of MongoTemple , at the end the execution is happening through a method

<S, T> List<T> doFind(String collectionName, Document query, Document fields, Class<S> sourceClass, Class<T> targetClass, CursorPreparer preparer)

and that method is invoked from an internal class called ExecutableFindOperationSupport . All those classes are package protected.

Is there any reason to make them package protected and not giving the chance to override them from an inherited class? Also is there any other way of running method queries with default criteria without appending them to all the queries?

The main problem in extending MongoTemplate as I've suggested in the previous question is need to override a lot of methods because MongoTemplate uses all them in its inner work. This way is not flexible and robust.

Want to suggest you another solution. You can implement Aspect that executes some code before invoking the MongoTemplate methods. You just add the additional criterion to every query the MongoTemplate receives.

Add the spring-boot-starter-aop to your dependencies. Enable AOP in the configuration class:

@Configuration
@EnableAspectJAutoProxy
public class AspectConfiguration {
}

And implement a small aspect that will do all works:

@Aspect
@Component
public class RepositoryAspect {
    @Before("execution(* org.springframework.data.mongodb.core.MongoTemplate.*(..))()")
    public void before(JoinPoint joinPoint) throws Throwable {
        Object[] args = joinPoint.getArgs();
        for (Object arg : args) {
            if (arg instanceof Query) {
                Query query = (Query) arg;
                // add your criteria to the query
                return;
            }
        }
    }
}

But keep in mind that this approach may lead to bad performace of executing queries. If you build a highload system, set your criterion is better way - it's the cost for fast work.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM