如何通过@IndexColumn中的数字选择Collection中的第n个元素?

时间:2010-10-15 07:46:22

标签: java hibernate orm hql

我有一个ItemEntity类,它有一个ImageEntity集合。我希望能够获取特定的ImageEntity,给定它在集合中的索引。例如,对于具有10个ImageEntity的ItemEntity,我希望第4个ImageEntity尽可能少的数据库命中。

我已经阅读了Hibernate In Action和Google搜索,但是我能找到的每一篇文档都非常简洁地描述@IndexColumn,没有详细的如何使用它的例子。

我可以使用item.getImages()来获取List< ImageEntity>,然后在那上面调用.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 个答案:

答案 0 :(得分:4)

您正在寻找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核心参考指南
  • JPA 2.0规范
    • 第4.6.17.2.2节算术函数