JPA мультиселект - PullRequest
       6

JPA мультиселект

1 голос
/ 08 февраля 2012

Я использую EclipseLink в качестве поставщика JPA.

Я хочу сделать запрос, чтобы получить все имена, которые соответствуют определенному IDs, с одним онлайн-запросом Criteria.

Root<UserAccount> root = criteria.from(UserAccount.class);
List<Selection<?>> select = new ArrayList<Selection<?>>();
    for (MyElement element : list) {
   Expression<String> firstName = root.get("firstName");
   Expression<String> lastName = root.get("lastName");
   Expression<Integer> id = root.get("id");
   select.add(criteria
                .multiselect(
                        firstName.alias(element.getId() + "_"
                                + element.getEntity() + "f"),
                        lastName.alias(element.getId() + "_"
                                + element.getEntity() + "l"))
                .where(criteriaBuilder.equal(id, element.getAuthorId()))
                .from(UserAccount.class)
                .alias(element.getId() + "_" + element.getEntity()));
}
criteria.multiselect(select);
TypedQuery<Tuple> q = em.createQuery(criteria);
for (Tuple t : q.getResultList()) {
        for (OverviewEntity element : list) {
 System.out.println("////"
                        + t.get(element.getId().toString() + "_"+element.getEntity()+"f",
                                String.class));

К element.getId() + "_" + element.getEntity() + "f" Я намерен создать уникальный псевдоним.

Проблема в том, что все, что я получаю, это null. Зачем? Как мне получить все это в одном запросе (чтобы он не занимал много времени)?

Ответы [ 2 ]

8 голосов
/ 08 февраля 2012

Ваш код кажется очень запутанным и слишком сложным.

JPQL

Select u.firstName, u.lastName, u.id from UserAccount u where u.id in (:ids)

Казалось бы,

По критериям это

Root<UserAccount> root = criteria.from(UserAccount.class);
criteria.multiselect(root.get("firstName"), root.get("lastName"), root.get("id"));
criteria.where(criteriaBuilder.in(root.get("id"), criteriaBuilder.parameter("ids"));
2 голосов
/ 08 февраля 2012

Как предлагается в комментариях, я бы пошел к более простому решению, как

List<Integer> myList = ....;  // place here your ids
TypedQuery<UserAccount> q = em.createQuery("select u from UserAccount u where u.id in (:myList)", UserAccount.class);

или эквивалентный запрос с использованием CriteriaBuilder и метамодели:

Root<UserAccount> root = q.from(UserAccount.class);
Expression<Integer> exp = root.get(UserAccount_.id);
Predicate predicate = exp.in(myList);
criteria.where(predicate);

Возвращаемое resultList содержит экземпляры сущностей, которые присоединены к PersistenceContext. Это означает, что вы сможете без труда получить свойства Transient.

Относительно производительности могут быть заметные различия только в экстремальных ситуациях, например, когда размер возвращаемого списка очень большой или когда вам приходится повторять этот запрос с высокой частотой. Но это требует глубокого анализа.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...