Сортировка по проекции JPA запроса UNION с использованием Criteria APIJAVA

Программисты JAVA общаются здесь
Ответить
Anonymous
 Сортировка по проекции JPA запроса UNION с использованием Criteria API

Сообщение Anonymous »

У меня есть следующий (упрощенный) код, который выполняет объединениеAll между двумя таблицами с использованием Criteria API и получает проекцию, заданную ProjectionDTO. Эти объекты являются лишь примерами.

Код: Выделить всё

public List
 someMethod(int offset, int size) {
HibernateCriteriaBuilder builder = entityManager.unwrap(Session.class).getCriteriaBuilder();

CriteriaQuery qUser = builder.createQuery(ProjectionDTO.class);
Root rootUser = qUser.from(UserEntity.class);
qUser.select(builder.construct(
ProjectionDTO.class,
rootUser.get("id").alias("field1"),
rootUser.get("role").alias("field2")
));

CriteriaQuery qItem = builder.createQuery(ProjectionDTO.class);
Root rootItem = qItem.from(ItemEntity.class);
qItem.select(builder.construct(
ProjectionDTO.class,
rootItem.get("quantity").alias("field1"),
rootItem.get("description").alias("field2")
));

CriteriaQuery qUnion = builder.unionAll(qUser, qItem);

List result = entityManager.createQuery(qUnion)
.setFirstResult(offset)
.setMaxResults(size)
.getResultList();
return result;
}
Прогноз предоставлен:

Код: Выделить всё

public class ProjectionDTO {

private Long field1;
private String field2;

public ProjectionDTO () {
}

public ProjectionDTO (Long field1, String field2) {
this.field1 = field1;
this.field2 = field2;
}
}
Это работает нормально, но мне не удалось реализовать предложение порядка с использованием псевдонимов. Тем более, что впоследствии я хочу иметь возможность правильно обрабатывать нумерацию страниц.
Я знаю, что могу заставить это работать, используя индекс, например:

Код: Выделить всё

qUnion.orderBy(builder.desc(builder.literal(1)));
Но, очевидно, это всего лишь обходной путь, а порядок (возможно, по нескольким столбцам) известен только во время выполнения. В идеале я хотел бы сделать что-то вроде:

Код: Выделить всё

Root
 rootProjection = qUnion.from(ProjectionDTO.class);
qUnion.orderBy(builder.desc(rootProjection.get("field1")));
Где я могу сделать заказ на основе псевдонима проекции. Но эта реализация явно неверна и не работает.
В идеале решение могло бы также обрабатывать предикаты при проекции, но на данный момент я могу добавить их в оба запроса по отдельности в качестве обходного пути. Так что это меньше беспокойства (но, тем не менее, это приятный бонус).
Я немного поигрался с подзапросами, так что, возможно, можно сделать и таким образом. В крайнем случае можно построить запрос вручную.

Подробнее здесь: https://stackoverflow.com/questions/794 ... iteria-api
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «JAVA»