QueryDsl ignoring predicate when using another @Query annotation

304 views
Skip to first unread message

Sebastiaan van den Broek

unread,
Mar 16, 2018, 6:48:40 AM3/16/18
to Querydsl
This is a copy of my Stackoverflow question at https://stackoverflow.com/questions/49312780/querydsl-ignoring-predicate-when-using-another-query-annotation

I have a repository looking like this (with other CRUD methods stripped)


import com.querydsl.core.types.Predicate;
import com.querydsl.core.types.dsl.StringPath;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.querydsl.QuerydslPredicateExecutor;
import org.springframework.data.querydsl.binding.QuerydslBinderCustomizer;
import org.springframework.data.querydsl.binding.QuerydslBindings;
import org.springframework.data.repository.CrudRepository;
import org.springframework.data.repository.query.Param;
import org.springframework.lang.NonNull;
import org.springframework.security.access.prepost.PreAuthorize;

import java.util.Optional;
import java.util.UUID;

@PreAuthorize("hasRole('" + Constants.ROLE_USER + "')")
public interface ProjectRepository extends CrudRepository<Project, UUID>, QuerydslPredicateExecutor<Project>, QuerydslBinderCustomizer<QProject> {
    @Override
    default void customize(@NonNull QuerydslBindings bindings, @NonNull QProject root) {
        bindings.bind(String.class).first(
                (StringPath path, String value) -> path.containsIgnoreCase(value));
        bindings.including(root.name);
        bindings.including(root.description);
    }

    @Override
    @Query("select p from Project p left join p.roles r left join r.account a where ?#{principal.username} = a.username")
    @NonNull
    Page<Project> findAll(@NonNull Predicate predicate, @NonNull Pageable pageable);
}

As you can see I have a @Query annotation that limits the response of findAll based on who the user is. This causes the Predicate to be ignored entirely. So if I search for anything, it still returns all objects the user has access to. If I remove the @Query annotation then the searching works correctly. But of course I want my security to be applied. Is this a bug in QueryDsl? Or simply a limitation? How could I make this work?

Ruben Dijkstra

unread,
Mar 16, 2018, 6:53:58 AM3/16/18
to Querydsl
Pretty sure you can choose between a few things, with Spring Data JPA.
In your current configuration, it seems to me you can opt to implement the query using @Query, or using the QuerydslPredicateExecutor logic.
You're doing both, and it seems the @Query takes precedence.

Hope this helps.

Best regards,
Message has been deleted

Sebastiaan van den Broek

unread,
Mar 16, 2018, 11:21:14 PM3/16/18
to Querydsl
Would you have any suggestions on how to make this work? It doesn't seem like much of a stretch to have some kind of security constraints and want to filter based on search constraints at the same time? How are people doing this normally?

Best regards,

Sebastiaan

Ruben Dijkstra

unread,
Mar 17, 2018, 4:27:30 AM3/17/18
to Querydsl
You can use @PostFilter for such things, or adjust the query per case.
I would go with adjusting the query personally, since it allows you to reason about runtime performance, and gives you fine grained control about when to adjust the query and when to skip it, i.e. backend statistics.

If you need a real example, or more in-depth coaching, I suggest you look for the Spring Data Gitter.
Because they wrote this integration they are in a better position to offer support for it, far more than I could do.

Best regards,
Ruben

--
You received this message because you are subscribed to the Google Groups "Querydsl" group.
To unsubscribe from this group and stop receiving emails from it, send an email to querydsl+unsubscribe@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply all
Reply to author
Forward
0 new messages