【问题标题】:Hibernate Complex JoinHibernate 复杂连接
【发布时间】:2017-02-24 23:16:12
【问题描述】:

所以我们有 2 个对象,每个对象都映射到一个 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;
}

一个 Dispute 可以有 0 个或多个 StatusInfo 与之关联。

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

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

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

关于如何使用 HQL 解决此问题的任何想法?我还能回来的地方:

List<Dispute>

感谢您的反馈。

谢谢!

【问题讨论】:

  • 请添加适合您情况的 sql 查询
  • 你不能。争议的状态信息是争议的状态信息。他们全部。这不取决于您从数据库中获取争议的方式。如果您想要争议的最新状态信息,您需要一个选择状态信息的查询。类似select dispute, statusInfo from Dispute d join d.statusInfos statusInfo where...

标签: hibernate join hql


【解决方案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&lt;StatusInfo&gt;,您可以添加一个临时方法来帮助您获取对象或获取 null 而无需担心集合语义:

@Transient
public StatusInfo getLatestStatusInfo() {
  if ( statusInfos.isEmpty() ) {
    return null;
  }
  else if ( statusInfos.size() == 1 ) {
    return statusInfos.get( 0 );
  }
  else {
    // you could add logic here to do the sort in-memory 
    // for cases where you may have the full collection
    // but still want to obtain the last entry ...
  }
}

【讨论】:

  • 似乎正是我一直在寻找的信息。我一定会试一试的!非常感谢。
  • 这正是我所需要的。我可以看到这些过滤器在哪里非常有用。真的很感谢你在这里插话。
  • @PaulAckley 很高兴为您提供帮助。
猜你喜欢
  • 2010-12-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-06-22
  • 2020-03-06
  • 1970-01-01
相关资源
最近更新 更多