Hibernate延迟初始化集合,提示Oracle DB

时间:2014-05-22 11:08:34

标签: java sql oracle hibernate hints

我有懒惰初始化集合的实体:

SomeEntity someEntity = template.findByNamedQuery("queryName", entityId);
if (someEntity != null) {
    Hibernate.initialize(someEntity.getChildCollection());
}

Hibernate生成SQL:

SELECT 
  t.COL1 AS COL1_,
  t.COL2 AS COL2_,
  ...
  t.COLN AS COLN_
FROM SCHEMA.TABLE t
WHERE t.COLX = :1
ORDER BY t.COL1 ASC;

列COLX上有索引IDX_COLX。

但由于某些未知原因,Oracle有时不使用此索引并在表上使用完全扫描。我不控制数据库,但有人告诉我(由db admin),解决方法是传递Oracle的提示。

这样的事情:

SELECT /*+ index(t IDX_COLX) */
  t.COL1 AS COL1_,
  t.COL2 AS COL2_,
  ...
  t.COLN AS COLN_
FROM SCHEMA.TABLE t
WHERE t.COLX = :1
ORDER BY t.COL1 ASC;

有没有简单的方法强制hibernate将这些附加信息附加到生成的SQL查询? 我不想因为一些Oracle错误或配置错误而重写整个应用程序。

我使用hibernate 3.3.2。

修改

我尝试了StuPointerException给出的解决方案,生成的SQL看起来像:

/*+ index(t IDX_COLX) */
SELECT
  t.COL1 AS COL1_,
  t.COL2 AS COL2_,
  ...
  t.COLN AS COLN_
FROM SCHEMA.TABLE t
WHERE t.COLX = :1
ORDER BY t.COL1 ASC;

在Oracle SQL Developer中测试过,如果放在SELECT语句之前,Oracle似乎不会识别此提示。

1 个答案:

答案 0 :(得分:0)

您可以通过在use_sql_comments上启用媒体资源HibernateSessionFactory来实现此目的:

<property name="use_sql_comments">true</property>

然后您就可以执行此操作:

String hql = "from SomeEntity e where e.COLX = :colx";
List result = session.createQuery(hql)
        .setString("colx", "xyz")
        .setComment("+ index(t IDX_COLX)")
        .list();

这确实意味着您必须对代码中的关系进行更多控制,这有点痛苦。

祝你好运!