Как выбрать n-й элемент в коллекции по номеру в @IndexColumn? - PullRequest
1 голос
/ 15 октября 2010

У меня есть класс ItemEntity, который имеет коллекцию ImageEntity.Я хочу иметь возможность извлекать определенный ImageEntity, учитывая его индекс в коллекции.Например, для ItemEntity с 10 ImageEntity я хочу, чтобы 4-е ImageEntity было как можно меньшим количеством обращений к базе данных.

Я прочитал Hibernate In Action и гуглил, но каждая часть документации, которую я могу найти, очень краткаяв описании @IndexColumn, без подробных примеров того, как его использовать.

Я могу использовать item.getImages () для получения List , а затем вызвать .get (4) для этого .. ноэто включает загрузку всей коллекции в память, чтобы иметь возможность вызывать get () для нее.

Я хотел бы сделать что-то вроде:

int itemId = 111; // id of the item I want to fetch the image for
int wantImageNum = 4; // index of the image I want, in the item's list
imageId = .. somehow get the id of the 4th ImageEntity ..;
ImageEntity img = session.load(ImageEntity.class, imageId);

Я использовал @IndexColumnчтобы позволить Hibernate управлять упорядочением ImageEntity в коллекции, например:

public class ItemEntity {
...
 @ManyToMany(cascade={CascadeType.MERGE,
    CascadeType.PERSIST,
    CascadeType.REFRESH}, fetch=FetchType.LAZY)
 @JoinTable(name = "ItemImages",
   joinColumns = {
    @JoinColumn(name="item_id", referencedColumnName="id") // id in this class           
   },
   inverseJoinColumns = {
    @JoinColumn(name="image_id") // id in ImageEntity
   }
 )
 @org.hibernate.annotations.IndexColumn(name="idx", base=1)
 private List images = new ArrayList();

Таким образом, существует «таблица соединений», которая выглядит следующим образом:

table ItemImages (
    item_id
    image_id
    idx
)

Я мог бы сделать что-тоочень грязный с простым SQL, то есть

select image_id from ItemImages where item_id = :itemId and idx = :wantImageNum;

Это явно ужасно.Я не могу воспользоваться подобным приемом, используя запросы HQL или Criteria, поскольку ItemImages не является сопоставленной сущностью, а таблицей соединений, управляемой Hibernate.

1 Ответ

4 голосов
/ 15 октября 2010

Функция index() HQL - это то, что вы ищете:

select image
from ItemEntity item
join item.images image
where index(image) = 4
and item.id = 111

Он был стандартизирован в JPA 2.0 также как INDEX. Из спецификации:

4.6.17.2.2 Арифметические функции

functions_returning_numerics::=
        ABS(simple_arithmetic_expression) |
        SQRT(simple_arithmetic_expression) |
        MOD(simple_arithmetic_expression, simple_arithmetic_expression) |
        SIZE(collection_valued_path_expression) |
        INDEX(identification_variable)

(...)

Функция INDEX возвращает целочисленное значение, соответствующее положение его аргумента в упорядоченном список. Функция INDEX может быть только применяется к идентификации переменных обозначая типы, для которых заказ столбец был указан.

В следующем примере studentWaitlist это список студенты, для которых столбец заказа имеет было указано:

SELECT w.name
FROM Course c JOIN c.studentWaitlist w
WHERE c.name = ‘Calculus’
AND INDEX(w) = 0

Ссылки

  • Справочное руководство по Hibernate Core
  • JPA 2.0 Спецификация
    • Раздел 4.6.17.2.2 Арифметические функции
...