Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/react-native/7.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 为什么我的查询返回列表中至少有一个参数的所有项,而不是列表中所有参数的参数?_Java_Spring_Hibernate_Jpa_Hibernate Criteria - Fatal编程技术网

Java 为什么我的查询返回列表中至少有一个参数的所有项,而不是列表中所有参数的参数?

Java 为什么我的查询返回列表中至少有一个参数的所有项,而不是列表中所有参数的参数?,java,spring,hibernate,jpa,hibernate-criteria,Java,Spring,Hibernate,Jpa,Hibernate Criteria,我有一个SpringBoot应用程序,我正在进行过滤。用户可以通过标签过滤广告(广告标签是多对多的,第三个表格)。一切正常,但当我发送标签列表进行筛选时,我的查询将返回至少有1个标签的所有广告的列表,而不是只返回包含过滤器中所有标签的广告。如果我只使用一个标记进行查询,一切都正常,但当我发送一个列表时,上面的情况正在发生。这是我的筛选方法: @Override public List<AdsDTO> findAll(AdsSubGroup adssubgroup, Long

我有一个SpringBoot应用程序,我正在进行过滤。用户可以通过标签过滤广告(广告标签是多对多的,第三个表格)。一切正常,但当我发送标签列表进行筛选时,我的查询将返回至少有1个标签的所有广告的列表,而不是只返回包含过滤器中所有标签的广告。如果我只使用一个标记进行查询,一切都正常,但当我发送一个列表时,上面的情况正在发生。这是我的筛选方法:

@Override
    public List<AdsDTO> findAll(AdsSubGroup adssubgroup, Long userId, String status, String adsType, 
                                String businessType, Long adsGroupId, String region, Integer fromPrice, 
                                Integer toPrice, Boolean fixedPrice, Boolean freeDelivery, Boolean productWarranty, 
                                Boolean urgentSales, Boolean hasImage, Integer pageNumber, Integer pageSize, List<String> tags) {

     CriteriaBuilder builder = em.getCriteriaBuilder();
     CriteriaQuery<Ads> query = builder.createQuery(Ads.class);
     Root<Ads> ads = query.from(Ads.class);
    // query.orderBy(builder.desc(ads.get("adsDate")));
     List<Predicate> predicates = new ArrayList<>();
     Join<Ads, JwtUser> adsUsersJoin = ads.join("users");
     Join<Ads, AdsSubGroup> adsAdsSubGroupJoin = ads.join("adssubgroup");
     Join<Ads, Tag> tagsJoin = ads.join("adsTags");
     In<String> in = builder.in(tagsJoin.get("name"));
     
        
          if (tags != null && tags.size() > 0) { 
              
              for (String tag : tags) {
                  in.value(tag);
             
              }
              predicates.add(in);
          }

          query.select(ads);
          query.distinct(true);
     query.where(predicates.toArray(new Predicate[0]));
     if(!(pageNumber==null && pageSize==null)) {
         TypedQuery<Ads> typedQuery = em.createQuery(query);
         typedQuery.setFirstResult((pageNumber-1)*pageSize);
         typedQuery.setMaxResults(pageSize);
         List<Ads> adsList = typedQuery.getResultList();
         return AdsConverter.convertToAdsDTO(adsList);
     }else {
         List<Ads> adsList = em.createQuery(query).getResultList();
         return AdsConverter.convertToAdsDTO(adsList);
     }
 
 }
@覆盖
公共列表findAll(AdsSubGroup、长用户ID、字符串状态、字符串adsType、,
字符串业务类型,长adsGroupId,字符串区域,整数fromPrice,
整数定价、布尔固定价格、布尔免费送货、布尔产品保修、,
布尔值urgentSales、布尔值hasImage、整数页码、整数页面大小、列表标记){
CriteriaBuilder=em.getCriteriaBuilder();
CriteriaQuery=builder.createQuery(Ads.class);
根ads=query.from(ads.class);
//query.orderBy(builder.desc(ads.get(“adsDate”));
列表谓词=新的ArrayList();
Join-adsUsersJoin=ads.Join(“用户”);
Join-adssubjoin=ads.Join(“adssubgroup”);
Join tagsJoin=ads.Join(“adsTags”);
In=builder.In(tagsJoin.get(“name”);
如果(tags!=null&&tags.size()>0){
用于(字符串标记:标记){
in.值(tag);
}
谓词.add(in);
}
查询。选择(ads);
query.distinct(true);
query.where(谓词.toArray(新谓词[0]);
如果(!(pageNumber==null&&pageSize==null)){
TypedQuery TypedQuery=em.createQuery(查询);
typedQuery.setFirstResult((pageNumber-1)*pageSize);
typedQuery.setMaxResults(页面大小);
List adsList=typedQuery.getResultList();
返回adscoverter.converttoadto(adsList);
}否则{
List adsList=em.createQuery(query).getResultList();
返回adscoverter.converttoadto(adsList);
}
}

如何修复该查询仅返回列表中所有标记的广告?

问题在于方法,查询是错误的

例如,您应该使用子查询检查每个文章是否有N个条目,其中N是输入的标记数

诸如此类:

//Subquery with count
Subquery<Long> countTagsSq = query.subquery(Long.class);
Root<Ads> rootSQ = countTagsSq.from(Ads.class);
Join<Ads,Tag> joinTagSQ = rootSQ.join("adsTags");

//We set the where condition by Ads id (I don't know what the attribute is called)
countTagsSq.where(
    cb.and(
        builder.equal(rootSQ.get("id"),ads.get("id")),
        joinTagSQ.get("name").in(tags)
    )
);
countTagsSq.select(builder.count(joinTagSQ ));

// Change your query where clause
query.where(cb.equal(countTagsSQ.getSelection(),Long.valueOf(tags.size())))
//带计数的子查询
Subquery countTagsSq=query.Subquery(Long.class);
Root rootSQ=countTagsSq.from(Ads.class);
Join joinTagSQ=rootSQ.Join(“adsTags”);
//我们通过Ads id设置where条件(我不知道该属性叫什么)
countTagsSq.where(
cb.和(
builder.equal(rootSQ.get(“id”)、ads.get(“id”),
joinTagSQ.get(“name”).in(标记)
)
);
countTagsSq.select(builder.count(joinTagSQ));
//更改查询where子句
query.where(cb.equal(countTagsSQ.getSelection(),Long.valueOf(tags.size()))
这样,如果标签大小为10,它将返回包含您输入的10个标签的广告