简体   繁体   English

JPA 规范在尝试将 OR 谓词组合在一起时不起作用

[英]JPA Specifications not working when trying to OR predicates together

I'm having trouble trying to get a working Specification for this query.我在尝试获取此查询的工作规范时遇到问题。 My data model looks something like this:我的数据 model 看起来像这样:

            Item { 
                Person person, 
                Place place
            }

            Person {
                Address address
            }

            Place {
                Address address
            }

            Address {
                String country
                String state
            }

An item can have either a Person or a Place associated with it, but not both.一个项目可以关联一个人或一个地点,但不能同时关联两者。 I want to query a list of Items based on if their Address matches either an associated Person or Place's address by searching against country AND state. My current implementation looks something like this:我想通过搜索国家和 state 来根据地址是否与关联的人或地点的地址匹配来查询项目列表。我当前的实现如下所示:

            public static Specification<Item> locationIs(String country, String state) {
                return (root, query, criteriaBuilder) -> {
                    Expression<String> personCountry = root.get("person").get("address").get("country");
                    Expression<String> placeCountry = root.get("place").get("address").get("country");
                    Expression<String> personState = root.get("person").get("address").get("state");
                    Expression<String> placeState = root.get("place").get("address").get("state");

                    Predicate personCountryMatch = criteriaBuilder.like(personCountry, "%" + country + "%");
                    Predicate personStateMatch = criteriaBuilder.like(personState, "%" + state + "%");
                    Predicate personMatch = criteriaBuilder.and(personCountryMatch, personStateMatch);

                    Predicate placeCountryMatch = criteriaBuilder.like(placeCountry, "%" + country + "%");
                    Predicate placeStateMatch = criteriaBuilder.like(placeState, "%" + state + "%");
                    Predicate placeMatch = criteriaBuilder.and(placeCountryMatch, placeStateMatch);

                    Predicate match = criteriaBuilder.or(personMatch, placeMatch);

                    return match
                };
            }

If I return just personMatch or just placeMatch it appears to work perfectly for searching on that, but as soon as I try to or them together the whole query returns no results.如果我只返回 personMatch 或只返回 placeMatch,它似乎可以完美地搜索它,但是一旦我尝试将它们它们放在一起,整个查询就不会返回任何结果。 I've tried creating Specifications from each predicate and combining them that way using, same result.我已经尝试从每个谓词创建规范并使用相同的结果组合它们。

Ended up just using subqueries for this instead, did something like最终只是为此使用子查询,做了类似的事情

criteriaBuilder.or(criteriaBuilder.exists(subquery1), criteriaBuilder.exists(subquery2))

And that worked fine那很好用

While subqueries can be a good alternative, the query you seemed to be aiming for originally would have been:虽然子查询可能是一个不错的选择,但您最初的目标查询似乎是:

Join<Person> person = root.join("person", JoinType.LEFT);
Join<Person> place = root.join("place", JoinType.LEFT);

Predicate personCountryMatch = criteriaBuilder.like(person.get("country"), "%" + country + "%");
Predicate personStateMatch = criteriaBuilder.like(person.get("state"), "%" + state + "%");
Predicate personMatch = criteriaBuilder.and(personCountryMatch, personStateMatch);

Predicate placeCountryMatch = criteriaBuilder.like(place.get("country"), "%" + country + "%");
Predicate placeStateMatch = criteriaBuilder.like(lace.get("state"), "%" + state + "%");
Predicate placeMatch = criteriaBuilder.and(placeCountryMatch, placeStateMatch);

Predicate match = criteriaBuilder.or(personMatch, placeMatch);

return match

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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