是否可以获取休眠 sql 限制的连接表的 SQL 别名?

2022-09-04 01:53:55

我有一个 Person 类,它有一个 String 别名集合,表示该人可能经过的其他名称。例如,克拉克·肯特(Clark Kent)可能有别名“超人”和“钢铁之躯”。德怀特·霍华德也有一个别名“超人”。

@Entity
class Person {

  @CollectionOfElements(fetch=FetchType.EAGER)
  Set<String> aliases = new TreeSet<String>();

Hibernate在我的数据库中创建了两个表,Person和Person_aliases。Person_aliases是一个连接表,其中包含Person_id和元素的列。假设Person_aliases具有以下数据

--------------------------------
| Person_id     | element      |
--------------------------------
| Clark Kent    | Superman     |
| Clark Kent    | Man of Steel |
| Dwight Howard | Superman     |
| Bruce Wayne   | Batman       |
--------------------------------

我想为所有别名为“超人”的人进行休眠标准查询。

由于太长而无法在此处列出的原因,我真的想使其成为一个 Criteria 查询,而不是 HQL 查询(除非可以对 Criteria 对象添加 HQL 限制,在这种情况下,我全神贯注)或原始 SQL 查询。由于根据如何使用休眠条件查询 String 集合中具有值的对象?因此不可能使用 CriteriaAPI 引用值类型集合的元素,因此我认为我会在 criteria 对象上添加 SqlRestriction。

Criteria crit = session.createCriteria(Person.class);
crit.add(Restrictions.sqlRestriction("XXXXX.element='superman'");

希望Hibernate会创建一个SQL语句,如

    select *
from
    Person this_ 
left outer join
    Person_aliases aliases2_ 
        on this_.id=aliases2_.Person_id 
where
    XXXXX.element='superman' 

但是,我需要在SQL查询中用Person_aliases表的表别名填写XXXXX,在这种情况下,这将是“aliases2_”。我注意到,如果我需要对Person表别名的引用,我可以使用{alias}。但这不起作用,因为 Person 是此条件的主表,而不是Person_aliases。

我需要为XXXXX填写什么?如果没有像{alias}这样漂亮的替代令牌,那么有没有办法让我进入休眠状态,告诉我这个别名会是什么?我注意到一个名为generationAlias()org.hibernate.util.StringHelper类的方法。这是否有助于我预测别名会是什么?

我真的,真的很想避免硬编码“aliases2_”。

感谢您抽出宝贵时间接受采访!


答案 1

正如xmedeko所暗示的那样,当你想做:

crit.add(Restrictions.sqlRestriction(
    "{alias}.joinedEntity.property='something'"));

你需要做的是:

crit.createCriteria("joinedEntity").add(Restrictions.sqlRestriction(
    "{alias}.property='something'"));

这为我解决了类似的问题,而无需去HQL


答案 2

标准 API 似乎不允许查询元素集合,请参阅 HHH-869(仍处于打开状态)。因此,要么尝试建议的解决方法 - 我没有 - 要么切换到HQL。以下 HQL 查询将起作用:

from Person p where :alias in elements(p.aliases)