【问题标题】:Hibernate criteria, distinct association property休眠标准,不同的关联属性
【发布时间】:2018-01-01 15:35:29
【问题描述】:

假设我至少有这两个实体:

class Person {
   String firstname, lastname;

   Address address;

   ManyOtherPropertiesAndEntities ...;
}

class Address {
      String street;
      Country country;   
}

现在,我想查询 Person 表和 ONLY 住在不同街道上的人。

也就是说,忽略所有住在同一条街上的人,只返回这些人中的一个,任何一个。

如何执行这样的查询?

这可能使用 Criteria 吗?

 Criteria criteria = session.createCriteria(Person.class, "person");

 Criteria addressCriteria = criteria.createCriteria("address")

 criteria.setProjection(
                    Projections.distinct(
                        Projections.projectionList().add(Projections.property("address.street"))
                    )
            );

这真的行不通。

我也尝试过:

projectionList.add( Projections.sqlProjection("DISTINCT ON ( address.street ), ... ", columns.toArray(new String[columns.size()]), types.toArray(new Type[types.size()])));

但也没有结果。

>>>>>>>>>>>>>>>>>>>>>>>编辑

我能够让它运行,并生成一个 SQL 查询,该查询实际上以纯 sql 模式返回结果,但在休眠时似乎返回零:

List<String> columns = Lists.lst();
                                        List<Type> types     = Lists.lst();

                                        bondCriteria.setProjection(
                                                Projections.sqlProjection ("DISTINCT ON ( tvmux2_.polarization ) * "
                                                        , columns.toArray (new String[columns.size()])
                                                        , types.toArray   (new Type[types.size()])
                                                )

                                                // Projections.projectionList().add(Projections.distinct(Projections.property("polarization")))
                                        );

                                        ResultTransformer resultTransformer = new ResultTransformer() {
                                                @Override
                                                public List transformList( List collection ) {
                                                        return null;
                                                }

                                                @Override
                                                public Object transformTuple( Object[] tuple, String[] aliases ) {
                                                        return null;
                                                }
                                        };

                                        bondCriteria.setResultTransformer(resultTransformer);

* ITS 2017 和 SO 仍然没有包含一个合适的编辑器来轻松格式化代码,因此缩进和复制和粘贴不是一个完整的地狱。随意水平滚动。 *

这基本上会生成以下查询

select DISTINCT ON ( tvmux2_.polarization ) *  from TvChannelBond this_ inner join TvChannel tvchannel1_ on this_.channel=tvchannel1_.id inner join TvMux tvmux2_ on this_.mux=tvmux2_.id where this_.enabled=true order by tvmux2_.polarization asc limit 100

在非休眠模式下返回结果。

但是,由于 sqlProjection 方法需要补充 3 个参数,所以我不确定在第二个和第三个参数中添加什么。类型不能是预定义的 Hibernate 类型,如 DOUBLE、STRING 等。

调试进入resultTransformer时,它进入零长度tuple[]和aliases[]的transformTuple。

可能与 sqlProjection 零长度 类型和列列表有关。

【问题讨论】:

  • 只是一个问题:你为什么要使用 Hibernate Criteria?它已弃用且不受支持。顺便说一句,对于这种要求,我建议使用原生查询。
  • @galovics 已经有一个大的标准查询。这只是一个插件选项,我想避免为这种情况重写整个查询构建器。标准查询已弃用?现在有什么建议?不要说 HQL。
  • @galovics 看到这个stackoverflow.com/a/45325401/961018 ...现在的问题是如何将该 sql 投影转换为休眠标准。
  • 我们鼓励您使用 JPA 标准中的 Criteria-API,而不是 Hibernate 的专有 Criteria-API。
  • ^ ^ 更新了编辑

标签: java sql hibernate criteria hibernate-criteria


【解决方案1】:

在 SQL 中,你可以这样做:

SELECT p.*
FROM Address a
INNER JOIN Person p ON ...
GROUP BY a.Street
HAVING p.id = MIN(p.id)

此语句从Address 中为每个不同的Street 选择具有最小id 值的Person。除了MIN(p.id),您当然可以使用任何其他字段和聚合函数来匹配每条街道的一个人; MAX(p.id) 可以,MIN(p.lastname) 不行,如果一条街上可以有多个“史密斯”。

您能否将上述 SQL 转换为您的 Criteria 查询?

【讨论】:

  • 更新了一个编辑。基于不同的 sql 查询,可在此处找到:stackoverflow.com/a/45325401/961018 请注意,我知道表和属性已更改,但这在这里并不重要。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-09-25
  • 1970-01-01
  • 1970-01-01
  • 2012-01-21
  • 2011-12-29
  • 1970-01-01
相关资源
最近更新 更多