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 odpowiedzi
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.
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
Podobne pytania
Nowe pytania
jpa-2.0
Ten znacznik jest przeznaczony na pytania dotyczące wersji 2.0 interfejsu API Java Persistence. Celem JPA 2.0 było zajęcie się funkcjami, które były obecne u niektórych popularnych dostawców ORM, ale nie mogły uzyskać zgody na JPA 1.0.