如何使用jpa规范添加distinct属性进行查询

问题描述 投票:1回答:1

我正在使用jhipster标准和jpa规范来实现端点进行研究。

好吧它工作,但继续发送给我重复。

有这个模型的prestations

public class Prestation extends AbstractAuditingEntity implements Serializable {

private static final long serialVersionUID = 1L;

@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "sequenceGenerator")
@SequenceGenerator(name = "sequenceGenerator")
private Long id;

@NotNull
@Column(name = "jhi_label", nullable = false)
private String label;

@Column(name = "description")
private String description;

@Column(name = "unit")
private String unit;

@NotNull
@Column(name = "activated", nullable = false)
private boolean activated;

@ManyToOne(optional = false)
@NotNull
@JsonIgnoreProperties("prestations")
private SubCategory subCategory;

@OneToMany(mappedBy = "prestation", cascade = CascadeType.ALL, orphanRemoval = true)
private List<CompanyPrestation> companies = new ArrayList<>();

以及公司和Prestations之间的关系

@OneToMany(mappedBy = "company", cascade = CascadeType.ALL, orphanRemoval = true)
@LazyCollection(LazyCollectionOption.FALSE)
private List<CompanyPrestation> prestations = new ArrayList<>();

这是我用来创建我给存储库的规范的CompanySpecification类

public class CompanySpecification extends QueryService<Company> implements Specification<Company> {

private static final long serialVersionUID = 1L;
private CompanyCriteria criteria;

public CompanySpecification(CompanyCriteria criteria) {
    this.criteria = criteria;
}

@Override
public Predicate toPredicate(Root<Company> roots, CriteriaQuery<?> query, CriteriaBuilder builder) {

    Specification<Company> specification = Specification.where(null);
    if (criteria != null) {
        if (criteria.getName() != null) {
            specification = specification.or(buildStringSpecification(criteria.getName(), Company_.name));
        }
        if (criteria.getSiret() != null) {
            specification = specification.or(buildStringSpecification(criteria.getSiret(), Company_.siret));
        }
        if (criteria.getCodeAPE() != null) {
            specification = specification.or(buildStringSpecification(criteria.getCodeAPE(), Company_.codeAPE));
        }
        if (criteria.getLegalForm() != null) {
            specification = specification.or(buildStringSpecification(criteria.getLegalForm(), Company_.legalForm));
        }
        if (criteria.getVille() != null) {
            specification = specification
                    .and(buildReferringEntitySpecification(criteria.getVille(), Company_.address, Address_.ville));
        }
        if (criteria.getExercicePlace() != null && !criteria.getExercicePlace().getIn().isEmpty()) {
            Filter<ExercicePlace> exercicePlaceFilter = new Filter<>();
            exercicePlaceFilter.setIn(criteria.getExercicePlace().getIn().stream().map(ExercicePlace::valueOf)
                    .collect(Collectors.toList()));
            specification = specification.and(buildSpecification(exercicePlaceFilter, Company_.exercicePlace));
        }
        if (criteria.getCodePostal() != null) {
            specification = specification.and(buildReferringEntitySpecification(criteria.getCodePostal(),
                    Company_.address, Address_.codePostal));
        }
        if (criteria.getPrestationsId() != null) {
            specification = specification.and(buildSpecification(criteria.getPrestationsId(),
                    root -> root.join(Company_.prestations, JoinType.LEFT)
                            .join(CompanyPrestation_.prestation, JoinType.LEFT).get(Prestation_.id)));
        }
        if (criteria.getCatId() != null) {
            specification = specification.and(buildSpecification(criteria.getCatId(),
                    root -> root.join(Company_.prestations, JoinType.LEFT)
                            .join(CompanyPrestation_.prestation, JoinType.LEFT)
                            .join(Prestation_.subCategory, JoinType.LEFT).join(SubCategory_.category, JoinType.LEFT)
                            .get(Category_.id)));
        }
        if (criteria.getSubCatId() != null) {
            specification = specification.and(buildSpecification(criteria.getSubCatId(),
                    root -> root.join(Company_.prestations, JoinType.LEFT)
                            .join(CompanyPrestation_.prestation, JoinType.LEFT)
                            .join(Prestation_.subCategory, JoinType.LEFT).get(SubCategory_.id)));
        }
        if (criteria.getPrestationName() != null) {
            specification = specification.or(buildSpecification(criteria.getPrestationName(),
                    root -> root.join(Company_.prestations, JoinType.LEFT)
                            .join(CompanyPrestation_.prestation, JoinType.LEFT).get(Prestation_.label)));
        }
        if (criteria.getPriceMinimum() != null || criteria.getPriceMaximum() != null) {
            specification = specification.and((lroot, lquery, lcriteriaBuilder) -> {
                ListJoin<Company, CompanyPrestation> joinCompnayToCompanyPrestations = lroot
                        .join(Company_.prestations, JoinType.LEFT);
                if (criteria.getPriceMinimum() != null && criteria.getPriceMaximum() != null) {
                    return lcriteriaBuilder.between(
                            joinCompnayToCompanyPrestations.get(CompanyPrestation_.pricePerUnit),
                            criteria.getPriceMinimum().getGreaterOrEqualThan(),
                            criteria.getPriceMaximum().getLessOrEqualThan()
                    );
                } else if (criteria.getPriceMinimum() != null) {
                    return lcriteriaBuilder.greaterThanOrEqualTo(
                            joinCompnayToCompanyPrestations.get(CompanyPrestation_.pricePerUnit),
                            criteria.getPriceMinimum().getGreaterOrEqualThan());
                } else {
                    return lcriteriaBuilder.lessThanOrEqualTo(
                            joinCompnayToCompanyPrestations.get(CompanyPrestation_.pricePerUnit),
                            criteria.getPriceMaximum().getLessOrEqualThan());
                }
            });
        }
    }
    return specification.toPredicate(roots, query, builder);
}

这是我使用它的服务方法

@Transactional(readOnly = true)
public Page<CompanyDTO> findByCriteria(CompanyCriteria criteria, Pageable page) {
    log.debug("find by criteria : {}, page: {}", criteria, page);
    Specification<Company> spec = Specification.where(null);
    CompanySpecification specification =  new CompanySpecification(criteria);
    spec = (Specification<Company>) specification;
    Page<Company> vitrinesPage = companyRepository.findAll(spec, page);
    List<CompanyDTO> list = companyMapper.toDto(vitrinesPage.getContent());
    Page<CompanyDTO> listPage = new PageImpl<>(list, page, vitrinesPage.getTotalElements());
    return listPage;
}

我在Criteria Query中找到了一个独特的方法,但我真的不知道如何在我的规范中添加它。

请帮忙!

spring-data-jpa distinct hibernate-criteria criteria-api criteriaquery
1个回答
2
投票

在你的toPredicate方法里面,你能做到吗?

@Override
public Predicate toPredicate(Root<Company> roots, CriteriaQuery<?> query, CriteriaBuilder builder) {
    ....
    query.distinct(true);
    return ...;
}

来自> CriteriaQuery#distinct

虽然你想要做的事情可能是不可能的,但据说它是一个limitation of JPA

您可以尝试做的是,在获取后删除代码中的重复项,或者尝试覆盖equalshashCode方法以尝试破解不同的定义吗?

© www.soinside.com 2019 - 2024. All rights reserved.