春季数据 JPA 选择不同

2022-09-04 19:22:13

我有一种情况,我需要构建一个(地址是Person内部的地址实体)类型的查询。select distinct a.address from Person a

我正在使用规范来动态构建我的 where 子句,并使用函数来获取结果。问题是我不能使用规范来构建我的select子句,因此不能使用函数。findAll(Specification<T>)findAll(Spcification)

做这样的事情的最好方法是什么?


答案 1

由于这是谷歌中最重要的问题,我将在这里发布答案。

在规范中,您可以访问查询,因此您可以

query.distinct(true);

导致发出此类 SQL 的完整示例:

2015-04-27 12:03:39 EEST [7766-759] postgres@sales 日志: 执行 : 选择非同 t1.ID,t1.NAME,t1。WEBNAME, t1.网络秩序,t1。PVGROUPPARENT_ID,t1。SITE_ID从乘积变式 t0,PVGROUP t1 WHERE ((t0.PRODUCTTYPE_ID = $1) 和 (t0.PVGROUP_ID = t1.ID)) 2015-04-27 12:03:39 EEST [7766-760] postgres@sales 详细信息: 参数: $1 = '4608bdc9-d0f2-4230-82fd-b0f776dc2cfd'

public static Specification<PVGroup> byProductType(final ProductType pt) {
        return (final Root<PVGroup> root, final CriteriaQuery<?> query, final CriteriaBuilder builder) -> {

            query.distinct(true);
            final CollectionJoin<PVGroup, ProductVariant> jPV = root.join(PVGroup_.productVariant);

            final Path<ProductType> ptPath = jPV.get(ProductVariant_.productType);

            return builder.equal(ptPath, pt);
        };
    }
}

答案 2

我遇到了同样的问题,所以以防万一它能帮助某人,这就是我所做的:

规范正在转换为 where 子句,并且函数正在创建自己的 select 子句。因此,我们无法通过以某种方式使用该函数来解决此问题。我已经有扩展的自定义存储库,所以我添加了一个新方法:findAll(Specification<T>)findAll(Specification<T>)SimpleJpaRepository

@Override
    @Transactional(readOnly = true)
    public List<Object> findDistinctValues(Specifications<T> spec, String columnName) {
        return getQuery(spec, columnName).getResultList();
    }

    protected TypedQuery<Object> getQuery(Specification<T> spec, final String distinctColumnName) {

        CriteriaBuilder builder = em.getCriteriaBuilder();
        CriteriaQuery<Object> query = builder.createQuery(Object.class);
        Root<T> root = applySpecificationToCriteria(spec, query);

        if (null != distinctColumnName) {
            query.distinct(true);
            query.multiselect(root.get(distinctColumnName));
        }

        // We order by the distinct column, Asc
        query.orderBy(builder.asc(root.get(distinctColumnName)));

        return em.createQuery(query);
    }

applySpecificationToCriteria在课堂上。SimpleJpaRepository

现在您可以使用该方法。findDistinctValues


推荐