Nir*_*hah 11 java sql spring spring-data-jpa
我有一种情况,我需要构建一个select distinct a.address from Person a(其中地址是Person内部的Address实体)类型的查询.  
我正在使用Specification来动态构建我的where子句并使用该findAll(Specification<T>)函数来获取结果.问题是我不能使用规范来构建我的select子句,因此不能使用findAll(Spcification)函数.
做这样的事情最好的方法是什么?
我遇到了相同的问题,因此,如果它可以帮助某人,这就是我所做的:
规范被转换为where子句,并且findAll(Specification<T>)函数正在创建自己的select子句。因此,我们无法通过某种方式使用该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方法了。
由于它是google中的首要问题,因此我将在此处发布答案。
在规范中,您有权查询,因此您可以执行
query.distinct(true);
完整的示例,导致发出这样的SQL:
2015-04-27 12:03:39 EEST [7766-759] postgres @ sales日志:执行:从PRODUCTVARIANT中选择DISTINCT t1.ID,t1.NAME,t1.WEBNAME,t1.WEBORDER,t1.PVGROUPPARENT_ID,t1.SITE_ID t0,PVGROUP t1在哪里(((t0.PRODUCTTYPE_ID = $ 1)AND(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);
        };
    }
}
一个快速而肮脏的解决方案是使用以下方法过滤结果Set:
Set<...> set = new HashSet<...>( findAll( ... ) )
并确保equals()和hashCode()在域类上相关实现:-)
干杯,
| 归档时间: | 
 | 
| 查看次数: | 29210 次 | 
| 最近记录: |