Hibernate Complex Join

时间:2017-02-24 23:16:13

标签: hibernate join hql

所以我们有两个对象,每个对象都映射到一个db表。

public class Dispute {
  private Long disputeSeqNo;
  private List<StatusInfo> statusInfos;
}

public class StatusInfo {
  private Long statusSeqNo;
  private Date createdDt;
  private String statusCd;
  private Dispute dispute;
}

争议可以有0个或更多与之关联的StatusInfo。

目前,hibernate正在为每个Dispute返回所有StatusInfo对象。虽然在某些情况下这是期望的。但是我有一个用例:

  • 我只需要为每个争议显示最新的StatusInfo。
  • 此外,在同一显示器上,我需要能够按最新的StatusInfo.statusCd值进行排序。这种情况需要在数据库中进行,因为我的显示是分页的(使用hibernate分页工具)。 (检索后对数据进行排序实际上不是一个选项,因为会有很多行数据。)

我知道只使用普通的SQL我可以做到这一点,努力将其转换为HQL。

有关如何使用HQL解决此问题的任何想法?我仍然回来的地方:

List<Dispute>

感谢您的反馈。

谢谢!

1 个答案:

答案 0 :(得分:1)

您需要做的第一件事是在下面定义一个Hibernate过滤器。您只需在Dispute课程的顶部添加此注释即可。

@FilterDef( name = "dispute-with-latest-statusinfo" )

接下来,您需要在StatusInfo的集合中应用此命名过滤器,如下所示:

@OneToMany( mappedBy = "dispute" )
@Filter( 
  name = "dispute-with-latest-statusinfo",
  condition = "statusinfo_id = (select max(si.statusinfo_id) from 
    StatusInfo si WHERE si.dispute_dispute_id = dispute_dispute_id")
private List<StatusInfo> statusInfos;

为了满足您的第一个要求,您可以通过在会话上启用该过滤器然后执行查询来获取Dispute个实例及其最新StatusInfo的列表:

session.enableFilter( "dispute-with-latest-statusinfo" );
List<Dispute> disputes = session
  .createQuery( "FROM Dispute d JOIN FETCH d.statusInfos", Dispute.class )
  .getResultList()

为了按照您的要求对结果进行排序:

session.enableFilter( "dispute-with-latest-statusinfo" );
List<Dispute> disputes = session
  .createQuery( "FROM Dispute d JOIN FETCH d.statusInfos si ORDER BY si.status DESC", Dispute.class )
  .getResultList()

现在,如果您不想使用包含针对这些情况的单个元素的List<StatusInfo>,您可以添加一个临时方法来帮助您获取对象或获取{{1}无需担心集合语义:

null