【问题标题】:JPA support for outer joins without object relational mappingJPA 支持没有对象关系映射的外部连接
【发布时间】:2015-09-23 03:26:45
【问题描述】:

最近我不得不在两个没有对象关系映射的 JPA 实体之间使用外连接。根据规范和论坛帖子,只有在 JPA 级别映射实体时才支持外部联接。

下面的示例代码。要求是找到没有任何订单的客户。

@Entity
class Customer {
    private int id;
}
@Entity
class Order {
    private int customerId;
    public int getCustomerId() { return customerId; }
    public void setCustomerId(int customerId) { this.customerId = customerId ; }
}

就我而言,我必须选择原生查询来完成工作。

对于未来的 JPA 规范是否支持没有关系映射的外连接有什么想法吗?

谢谢 拉克什

【问题讨论】:

  • 抱歉,您能再解释一下您的问题吗?您是否定义了实体类但没有定义它们之间的关联?您可以发布您尝试过的代码吗?或许可以告诉我们您想要实现的目标。
  • 没错,JPA 实体没有在 JPA 级别定义任何关系。编辑以包含示例代码。在给定的场景中,JPA 不提供外连接。原因:它需要符合 2/2.1 规范的对象路径。
  • 那么为什么不使用关联“正确地”定义实体,让您的生活更轻松呢?定义这些实体之间的关系有什么缺点(除了你必须输入更多代码)?
  • @DuncanKinnear 这是个好问题。定义 JPA 级别 OR 映射很大程度上取决于情况。当涉及到一个实体“组成”另一个实体的情况时,它们是救命稻草,即实体 1 仅在实体 2 存在时才存在。但是,在所有情况下都不是必须的。例如。审计就是这样一个例子。我宁愿避免 OR 映射本身而不是映射,然后处理延迟/急切加载和相关的休​​眠会话边界问题。

标签: java hibernate jpa orm outer-join


【解决方案1】:

您可以使用 theta 样式的连接来模拟 INNER JOIN:

    select c, o
    from Customer c, Order o
    where c.id= o.customerId

大多数现代数据库引擎查询优化器会将其变成INNER JOIN equivalent anyway

【讨论】:

  • 谢谢。从逻辑上讲,这应该有效。将测试并恢复。
  • 我刚刚修改了 OP 中的实体定义。您能否建议修改您提到的 LEFT JOIN 查询?谢谢。
  • 查询返回所有,即有订单和没有订单的客户。但需要的是没有订单的客户。
  • 这就是 LEFT join 的工作原理。尝试为没有订单的客户提供 Dragan 答案。
【解决方案2】:

假设您在 Order 实体中有 customerId 字段 (Integer)。为了找到没有订单的客户,可以使用子查询避免外连接和原生查询:

select c from Customer c where id not in (select customerId from Order)

这样您就可以在 JPQL (HQL) 中实现相同的目标。

【讨论】:

  • 嗯,通常我们不会为了支持查询而添加列。在报告的情况下,客户已经有 orderId,在 Order 中有 customerId 是多余的,不是正确的方法。
  • 只要按照建议定义关联,就可以正常工作
  • 接受所需的答案。但是,我仍然会选择带有左外连接的本机查询以避免内部查询。谢谢。
猜你喜欢
  • 2020-06-25
  • 2019-12-14
  • 2016-07-21
  • 2017-10-21
  • 2012-03-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多