Jestem ciekaw, dlaczego przy klasie CriteriaBuilder JPA 2 można tworzyć takie zapytania. Załóżmy, że mam klasę User z utrwalonym String o nazwie name jako atrybut. Dlaczego mogę to napisać?

CriteriaBuilder builder = mgr.getCriteriaBuilder();

CriteriaQuery<User> crit = builder.createQuery(User.class);
Root<User> user = crit.from(User.class);                     // 1
crit.select(user)
    .where(builder.equal(user.get(User_.name), 2.5));        // 2

Po pierwsze, przy znaczniku 1: Dlaczego muszę ponownie wskazać User.class? Czy moje CriteriaQuery i tak nie ma wiedzieć, że interesują mnie użytkownicy? Czy ewentualne wstrzyknięcie tutaj innej klasy nie łamie bezpieczeństwa typu?

Po drugie, przy znaczniku 2: Właściwość name to String. Dlaczego mogę skompilować takie bzdury, porównując String z podwójnym? Innymi słowy, dlaczego sygnatura wywoływanej metody equal jest taka:

public Predicate equal(Expression<?> x, Object y)

Zamiast przypuszczalnie bardziej bezpiecznej wersji w następujący sposób?

public <T> Predicate equal(Expression<T> x, T y)

Czy inne struktury zapytań, takie jak Querydsl, zapewniłyby lepsze rozwiązanie tego problemu?

2
Jean-Philippe Pellet 19 październik 2012, 23:30

2 odpowiedzi

Najlepsza odpowiedź

Uważam, że aspekty związane z typem API JPA 2 Criteria zostały dodane w dość późnym momencie procesu specyfikacji. Dlatego nie wydaje się spójne.

Querydsl jest bardziej zwięzły niż JPA 2 Criteria API, a także bardziej bezpieczny dla czcionek. Querydsl używa kreatorów płynnych zamiast klasy fabrycznej do tworzenia predykatów, więc równoważną metodę można znaleźć tutaj http://www.querydsl.com/static/querydsl/2.8.0/apidocs/com/mysema/query/types/ expr/SimpleExpression.html#eq%28T%29

Jestem opiekunem Querydsl, więc ta odpowiedź jest stronnicza.

2
Timo Westkämper 20 październik 2012, 11:02

Specyficzne dla JPA, możesz również użyć Zapytania obiektu lub Zapytanie torpedowe(ale jest to wyspecjalizowane w HQL), które nie wymaga generowania modelu w czasie kompilacji. w każdym razie QueryDsl jest jednym z pierwszych, którzy zaimplementowali zapytania typu typesafe

2
tglman 9 październik 2013, 20:16