Как отфильтровать по названию факультета? - PullRequest
1 голос
/ 26 апреля 2020

Я хочу реализовать отложенную загрузку записей в таблице данных Primefaces (версия 7). У меня есть две сущности, одна называется Факультеты, а другая - Карьера, которые связаны между собой. В таблице данных правильно отображается список всех рас (включая разбиение на страницы и фильтрацию), проблема в том, что я не знаю, как отфильтровать расы по названию определенного факультета, так как я не знаю, как включить объединение в запросе, который я оставлю тогда.

Не могли бы вы подсказать мне, как его решить, пожалуйста?

Факультеты сущностей

public class Facultades implements Serializable {

private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Basic(optional = false)
@Column(name = "idfacultad")
private Integer idfacultad;
@Basic(optional = false)
@NotNull
@Size(min = 1, max = 100)
@Column(name = "nombre")
private String nombre;
@Size(max = 20)
@Column(name = "abreviatura")
private String abreviatura;
@OneToMany(cascade = CascadeType.ALL, mappedBy = "idfacultad")
private List<Carreras> carrerasList;}

Сущности Каррерас

public class Carreras implements Serializable {

private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Basic(optional = false)
@Column(name = "idcarrera")
private Integer idcarrera;
@Basic(optional = false)
@NotNull
@Size(min = 1, max = 150)
@Column(name = "nombre")
private String nombre;
@Basic(optional = false)
@NotNull
@Column(name = "tipo")
private int tipo;
@JoinColumn(name = "idfacultad", referencedColumnName = "idfacultad")
@ManyToOne(optional = false)
private Facultades idfacultad;}

Запрос findByParams

public List<Carreras> findByParams(int start, int size, String sortField, SortOrder sortOrder, Map<String, Object> filters) {
    CriteriaBuilder criteriaBuilder = em.getCriteriaBuilder();
    CriteriaQuery<Carreras> criteriaQuery = criteriaBuilder.createQuery(Carreras.class);
    Root<Carreras> root = criteriaQuery.from(Carreras.class);
    CriteriaQuery<Carreras> select = criteriaQuery.select(root);

    Join<Carreras, Facultades> facultad = root.join("idfacultad");

    if (sortField != null) {
        criteriaQuery.orderBy(sortOrder == SortOrder.DESCENDING ? criteriaBuilder.asc(root.get(sortField)) : criteriaBuilder.desc(root.get(sortField)));
    }

    if (filters != null && filters.size() > 0) {
        List<Predicate> predicados = new ArrayList<>();

        filters.entrySet().forEach((entry) -> {
            String key = entry.getKey();
            Object val = entry.getValue();
            if (!(val == null)) {
                // Construimos la expresion con los predicados que si existan
                Expression<String> expresion = root.get(key).as(String.class);
                Predicate predicado = criteriaBuilder.like(criteriaBuilder.lower(expresion), "%" + val.toString().toLowerCase() + "%");
                predicados.add(predicado);
            }
        });
        if (predicados.size() > 0) {
            criteriaQuery.where(criteriaBuilder.and(predicados.toArray(new Predicate[predicados.size()])));
        }
    }
    // Creamos la consulta
    TypedQuery<Carreras> consulta = em.createQuery(select);
    consulta.setFirstResult(start);
    consulta.setMaxResults(size);

    return consulta.getResultList();

}

1 Ответ

0 голосов
/ 07 мая 2020

Вам нужно вручную проверить, равен ли ключ фильтра объекту Facultades, и в этом случае создать предикат в объединенном выражении, которое вы уже создали:

if (key.equals("Facultad")) {
        expresion = facultad.get("nombre").as(String.class);
} else {
        expresion = root.get(key).as(String.class);
}
...