Spring data jpa规范:如何通过其子对象属性筛选父对象

7

我的实体类如下:

@Entity
@table
public class User {

    @OneToOne
    private UserProfile userProfile;

    // others
}


@Entity
@Table
public class UserProfile {

    @OneToOne
    private Country country;
}

@Entity
@Table
public class Country {
    @OneToMany
    private List<Region> regions;
}

现在我想获取特定地区的所有用户。我知道SQL,但我想用Spring Data JPA规范来完成它。以下代码不应该起作用,因为regions是一个列表,而我正在尝试与单个值匹配。如何获取地区列表并与单个对象进行比较?

 public static Specification<User> userFilterByRegion(String region){


        return new Specification<User>() {
            @Override
            public Predicate toPredicate(Root<User> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder criteriaBuilder) {

                return criteriaBuilder.equal(root.get("userProfile").get("country").get("regions").get("name"), regionalEntity);
            }
        };
    }

编辑:谢谢你的帮助。实际上我在寻找以下JPQL的等效条件查询。

SELECT u FROM User u JOIN FETCH u.userProfile.country.regions ur WHERE ur.name=:<region_name>
2个回答

7

试试这个。应该可以工作。

criteriaBuilder.isMember(regionalEntity, root.get("userProfile").get("country").get("regions"))

你可以通过在Region类中重写Equals方法(和Hashcode)来定义相等的条件。

谢谢您的帮助,但它在我的情况下无效。我需要使用JPA标准查询翻译以下内容。FROM User u JOIN FETCH u.userProfile.country.regions ur WHERE ur.name - maruf571

1
我的代码片段
// string constants make maintenance easier if they are mentioned in several lines
private static final String CONST_CLIENT = "client";
private static final String CONST_CLIENT_TYPE = "clientType";
private static final String CONST_ID = "id";
private static final String CONST_POST_OFFICE = "postOffice";
private static final String CONST_INDEX = "index";
...

@Override
public Predicate toPredicate(Root<Claim> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
    List<Predicate> predicates = new ArrayList<Predicate>();
    // we get list of clients and compare client's type
    predicates.add(cb.equal(root
                .<Client>get(CONST_CLIENT)
                .<ClientType>get(CONST_CLIENT_TYPE)
                .<Long>get(CONST_ID), clientTypeId));
    // Set<String> indexes = new HashSet<>();
    predicates.add(root
                .<PostOffice>get(CONST_POST_OFFICE)
                .<String>get(CONST_INDEX).in(indexes));
    // more predicates added
    return return andTogether(predicates, cb);
}

private Predicate andTogether(List<Predicate> predicates, CriteriaBuilder cb) {
    return cb.and(predicates.toArray(new Predicate[0]));
}

如果你确定只需要一个谓词,使用List可能会过度设计。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接