Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bad SQL génération with Criteria class and complex operand #1938

Open
guirak opened this issue Nov 13, 2024 · 4 comments
Open

Bad SQL génération with Criteria class and complex operand #1938

guirak opened this issue Nov 13, 2024 · 4 comments
Labels
status: invalid An issue that we don't feel is valid

Comments

@guirak
Copy link

guirak commented Nov 13, 2024

Hello,

I am having some trouble when generating queries with the Criteria class (org.springframework.data.relational.core.query)

It's seems not possible to make a query like : (a OR b) AND c => This will be generated as a OR b AND c : it's not the same result.

I have defined the following method to generate an OR's combination :

    private <T> Criteria createCriteria(
            final Class<T> entityClass,
            final BDFilterOr filter) {

        // Critères de chaque opérande

        return filter.getChildren()
                .stream()
                .map(child -> createCriteria(entityClass, child))
                .reduce(Criteria::or)
                .orElseThrow(() -> new MmiBadRequestException("Pas d'opérande généré pour le filtre OR"));
    }
    

And for the AND combination :

    private <T> Criteria createCriteria(
            final Class<T> entityClass,
            final BDFilterAnd filter) {

        // Critères de chaque opérande

        return filter.getChildren()
                .stream()
                .map(child -> createCriteria(entityClass, child))
                .reduce(Criteria::and)
                .orElseThrow(() -> new MmiBadRequestException("Pas d'opérande généré pour le filtre AND"));
    }

Doing this, I'm expecting to have an OR combination inside a AND combination rounded with parenthesis in the generated query. It's not the case, when the OR combination is the first operand of the AND combination.

To solve the problem, I have to ensure the OR sub criteria is not placed at the first position of a AND criteria : it can't be used in a generic engine...

Is this API still maintained ?
Is there any workaround to permit the use of this API in any OR / AND combination ?

Thank you.

@spring-projects-issues spring-projects-issues added the status: waiting-for-triage An issue we've not yet triaged label Nov 13, 2024
@mp911de mp911de added the status: waiting-for-feedback We need additional information before we can continue label Nov 14, 2024
@mp911de
Copy link
Member

mp911de commented Nov 14, 2024

The API intentionally follows a style that makes it seem like you would write some criteria to not interfere with AND and OR precedence. You can create groups of nested criteria. Have you seen our QueryMapperUnitTests that show various usages and combinations of Criteria?

@spring-projects-issues spring-projects-issues added status: feedback-provided Feedback has been provided and removed status: waiting-for-feedback We need additional information before we can continue labels Nov 14, 2024
@mp911de mp911de added status: waiting-for-feedback We need additional information before we can continue and removed status: feedback-provided Feedback has been provided labels Nov 14, 2024
@spring-projects-issues
Copy link

If you would like us to look at this issue, please provide the requested information. If the information is not provided within the next 7 days this issue will be closed.

@spring-projects-issues spring-projects-issues added the status: feedback-reminder We've sent a reminder that we need additional information before we can continue label Nov 21, 2024
@guirak
Copy link
Author

guirak commented Nov 27, 2024

Hello, thank you and sorry for this late response.

It's ok, I found my problem thanks to the given test code.

This following criteria :

        Criteria criteria = initial
                .and(Criteria.where("name").is("FooA")
                        .or(Criteria.where("name").is("FooB"))
                        .or(Criteria.where("name").is("FooC"))) //
                .and(Criteria.where("name").is("FooD")
                );

produces :

(person.name = ?[$1] OR (person.name = ?[$2]) OR (person.name = ?[$3])) AND (person.name = ?[$4])

while the following criteria :

        Criteria criteria = Criteria.empty()
                .or(Criteria.where("name").is("FooA"))
                .or(Criteria.where("name").is("FooB"))
                .or(Criteria.where("name").is("FooC")) 
                .and(Criteria.where("name").is("FooD")
                );

produces :

(person.name = ?[$1]) OR (person.name = ?[$2]) OR (person.name = ?[$3]) AND (person.name = ?[$4])

As it is not a direct usage and it's a generic code, I was doing the second one instead thinking I have the first one

Thank you.

@spring-projects-issues spring-projects-issues added status: feedback-provided Feedback has been provided and removed status: waiting-for-feedback We need additional information before we can continue status: feedback-reminder We've sent a reminder that we need additional information before we can continue labels Nov 27, 2024
@schauder schauder added status: invalid An issue that we don't feel is valid and removed status: waiting-for-triage An issue we've not yet triaged status: feedback-provided Feedback has been provided labels Nov 27, 2024
@schauder
Copy link
Contributor

Thanks for the feedback.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
status: invalid An issue that we don't feel is valid
Projects
None yet
Development

No branches or pull requests

4 participants