Построитель критериев В запросе списка строк - PullRequest
1 голос
/ 19 июня 2020

Я передаю следующее json из внешнего интерфейса:

{names: 'ABC MKL-56-2,ABC MKL-56-3'};

На уровне обслуживания я пытаюсь выполнить запрос in с помощью построителя критериев следующим образом:

public List<APDetails> getWP(String names) {
        CriteriaBuilder builder = em.getCriteriaBuilder();
        CriteriaQuery<APDetails> query = builder.createQuery(APDetails.class);
        Root<APDetails> root = query.from(APDetails.class);
        Predicate hasA = builder.in(root.get(APDetails_.names).in(Arrays.asList(names.split(","))));
        query.where(builder.and(hasA));
        List<APDetails> APs = em.createQuery(query.select(root)).getResultList();
        return APs;
    }

Я получаю следующую ошибку:

Error message: org.hibernate.hql.internal.ast.QuerySyntaxException: 
unexpected token: in near line 1, column 163 [select generatedAlias0 
from com.app.ow.APDetails as generatedAlias0 where generatedAlias0.names in (:param0, :param1) in ()]

1 Ответ

0 голосов
/ 19 июня 2020

Прежде всего, если вы используете springboot, я предлагаю вам расширить класс JpaSpecificationExecutor (отметьте здесь , здесь и здесь для дополнительная информация) из вашего APDetailsRepository (я думаю, вы их где-то используете ...):

public interface APDetailsRepository extends JpaRepository<APDetails, Long>, JpaSpecificationExecutor<APDetails> {

Затем попробуйте следующее:

@Autowired
public APDetailsRepository apDetailsRepository;

........

public List<APDetails> getWP(String names) {
    List<String> namesAsList = Arrays.asList(names.split(","));

    List<APDetails> listAPDetails = this.apDetailsRepository.findAll(createSpecification(namesAsList));

    return listAPDetails;
}

 public Specification<APDetails> createSpecification(List<String> names) {
    return new Specification<APDetails>() {
        private static final long serialVersionUID = 1L;

        @Override
        public Predicate toPredicate(Root<APDetails> root, CriteriaQuery<?> query, CriteriaBuilder builder) {
            List<Predicate> predicates = new ArrayList<Predicate>();

            if (names!= null && !names.isEmpty()) {
                List<Predicate> predicatesNames = new ArrayList<Predicate>();

                for (String name : names) {
                    predicatesNames.add(builder.equal(root.<String>get("names"), name));
                    //I believe that the "APDetails_.names" attribute is a String...
                }

                predicates.add(builder.or(predicatesNames.toArray(new Predicate[] {})));        
            }

            return builder.and(predicates.toArray(new Predicate[] {}));
        }
    };
}
...