我应该在此 JPQL 查询中包含 unique 吗?

2024-05-26

背景

我在 SO 和许多流行博客中看到了关于必要性的多个答案和问题distinctJPQL 中的关键字JOIN FETCH查询和有关PASS_DISTINCT_THROUGH查询提示。

例如,看这两个问题

  • 使用 JPA 和 Hibernate 时 DISTINCT 如何工作 https://stackoverflow.com/questions/1346181/how-does-distinct-work-when-using-jpa-and-hibernate
  • 在 JPA 上选择 DISTINCT https://stackoverflow.com/questions/42830497/select-distinct-on-jpa

和这些博客文章

  • 将 JPQL DISTINCT 关键字与 JPA 和 Hibernate 结合使用的最佳方法 https://vladmihalcea.com/jpql-distinct-jpa-hibernate
  • DISTINCT 传递 Hibernate 查询提示 https://in.relation.to/2016/08/04/introducing-distinct-pass-through-query-hint/
  • Hibernate 技巧:如何将 DISTINCT 应​​用于 JPQL 而不是 SQL 查询 https://thorben-janssen.com/hibernate-tips-apply-distinct-to-jpql-but-not-sql-query/

我缺少什么

现在我的问题是我无法完全理解到底什么时候distinctJPQL 查询中必须包含关键字。更具体地说,是否取决于使用哪种方法来执行查询(getResultList or getSingleResult).

下面是一个例子来阐明我的意思。

我从现在开始编写的所有内容都在 Ubuntu Linux 18.04 上进行了测试,使用 Java 8、Hibernate 5.4.13 和内存 H2 数据库(版本 1.4.200)。

假设我有一个Department实体具有lazy与 a 的双向一对多关系DepartmentDirector entity:

// Department.java
@Entity
public class Department {
    // ...
    private Set<DepartmentDirector> directors;

    @OneToMany(mappedBy = "department", fetch = FetchType.LAZY)
    public Set<DepartmentDirector> getDirectors() {
        return directors;
    }
    // ...
}

// DepartmentDirector.java
@Entity
public class DepartmentDirector {
    // ...
    private Department department

    @ManyToOne
    @JoinColumn(name = "department_fk")
    public Department getDepartment() {
        return department;
    }
    // ...
}

假设我的数据库当前包含一个部门(department1) 以及两名与之相关的董事。

现在我想通过其 uuid(主键)检索该部门及其所有主管。这可以通过以下方式完成JOIN FETCHJPQL查询:

String query = "select department from Department department left join fetch "
             + "department.directors where department.uuid = :uuid";

由于前面的查询使用了join fetch对于子集合,我希望它在发布时返回两个重复的部门:但是,这只在使用带有以下查询的查询时才会发生:getResultList方法而不是使用时getSingleResult方法。这在某种程度上是合理的,但我发现 Hibernate 的实现getSingleResult uses getResultList在窗帘后面所以我期待着NonUniqueResultException被扔掉。

我还简要浏览了 JPA 2.2 规范,但没有提到处理两种方法之间的重复项的区别,并且涉及此问题的每个代码示例都使用getResultList method.

结论

在我的例子中我发现JOIN FETCH执行的查询getSingleResult不会遇到我在本节中链接的资源中解释的重复实体问题背景.

如果上述说法是正确的,那就意味着同样的JOIN FETCH查询需要distinct如果执行getResultList,但在执行时不需要它getSingleResult.

我需要有人向我解释这是预期的情况还是我误解了什么。


Appendix

两次查询的结果:

  1. 查询运行的是getResultList方法。我按预期得到了两个重复的部门(这样做只是为了测试查询的行为,getSingleResult应该用来代替这个):

    List<Department> resultList = entityManager.createQuery(query, Department.class)
            .setParameter("uuid", department1.getUuid())
            .getResultList();
    
    assertThat(resultList).containsExactly(department1, department1); // passes
    
  2. 查询运行的是getSingleResult方法。我希望检索到相同的重复部门,因此NonUniqueResultException被扔掉。相反,检索到一个部门并且一切正常:

    Department singleResult = entityManager.createQuery(query, Department.class)
            .setParameter("uuid", department1.getUuid())
            .getSingleResult();
    
    assertThat(singleResult).isEqualTo(department1); // passes
    

有趣的问题。

首先我要指出的是getSingleResult()用于查询由于它们的性质总是返回单个结果(意思是:主要是聚合查询,例如SELECT SUM(e.id) FROM Entity e)。您的一个查询think,基于某些特定于业务领域的规则,应该返回单个结果,但并不真正符合条件。

话虽这么说,JPA 规范指出getSingleResult()应该扔NonUniqueResultException当查询返回多个结果时:

The NonUniqueResultException当以下情况时由持久化提供者抛出Query.getSingleResult or TypedQuery.getSingleResult被调用并且查询有多个结果。此异常不会导致当前事务(如果该事务处于活动状态)被标记为回滚。

然而,看看 Hibernate 的实现:

    @Override
    public R getSingleResult() {
        try {
            final List<R> list = list();
            if ( list.size() == 0 ) {
                throw new NoResultException( "No entity found for query" );
            }
            return uniqueElement( list );
        }
        catch ( HibernateException e ) {
            if ( getProducer().getFactory().getSessionFactoryOptions().isJpaBootstrap() ) {
                throw getExceptionConverter().convert( e );
            }
            else {
                throw e;
            }
        }
    }

    public static <R> R uniqueElement(List<R> list) throws NonUniqueResultException {
        int size = list.size();
        if ( size == 0 ) {
            return null;
        }
        R first = list.get( 0 );
        for ( int i = 1; i < size; i++ ) {
            if ( list.get( i ) != first ) {
                throw new NonUniqueResultException( list.size() );
            }
        }
        return first;
    }

事实证明,Hibernate 对“不止一个结果”的解释似乎是“不止一个”unique结果'。

事实上,我使用所有 JPA 提供商测试了您的场景,结果是:

  • Hibernate 确实返回重复项getResultList(),但是确实not由于特殊的方式抛出异常getSingleResult()已实施
  • EclipseLink 是唯一一个不会出现重复结果错误的软件getResultList()因此,getSingleResult() does not要么抛出异常(对我来说,这种行为只是逻辑上的,但事实证明,这完全是一个解释问题)
  • OpenJPA 和 DataNucleus 都返回重复的结果getResultList()并抛出异常getSingleResult()

Tl;DR

我需要有人向我解释这是预期的情况还是我误解了什么。

这实际上取决于您如何解释规范

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

我应该在此 JPQL 查询中包含 unique 吗? 的相关文章

  • Java new Date() 打印

    刚刚学习 Java 我知道这可能听起来很愚蠢 但我不得不问 System out print new Date 我知道参数中的任何内容都会转换为字符串 最终值是 new Date 返回对 Date 对象的引用 那么它是如何打印这个的呢 Mo
  • Spring Batch 多线程 - 如何使每个线程读取唯一的记录?

    这个问题在很多论坛上都被问过很多次了 但我没有看到适合我的答案 我正在尝试在我的 Spring Batch 实现中实现多线程步骤 有一个包含 100k 条记录的临时表 想要在 10 个线程中处理它 每个线程的提交间隔为 300 因此在任何时
  • Java中反射是如何实现的?

    Java 7 语言规范很早就指出 本规范没有详细描述反射 我只是想知道 反射在Java中是如何实现的 我不是问它是如何使用的 我知道可能没有我正在寻找的具体答案 但任何信息将不胜感激 我在 Stackoverflow 上发现了这个 关于 C
  • 如何找到给定字符串的最长重复子串

    我是java新手 我被分配寻找字符串的最长子字符串 我在网上研究 似乎解决这个问题的好方法是实现后缀树 请告诉我如何做到这一点或者您是否有任何其他解决方案 请记住 这应该是在 Java 知识水平较低的情况下完成的 提前致谢 附 测试仪字符串
  • 使用 Android 发送 HTTP Post 请求

    我一直在尝试从 SO 和其他网站上的大量示例中学习 但我无法弄清楚为什么我编写的示例不起作用 我正在构建一个小型概念验证应用程序 它可以识别语音并将其 文本 作为 POST 请求发送到 node js 服务器 我已确认语音识别有效 并且服务
  • 在 HTTPResponse Android 中跟踪重定向

    我需要遵循 HTTPost 给我的重定向 当我发出 HTTP post 并尝试读取响应时 我得到重定向页面 html 我怎样才能解决这个问题 代码 public void parseDoc final HttpParams params n
  • Android:捕获的图像未显示在图库中(媒体扫描仪意图不起作用)

    我遇到以下问题 我正在开发一个应用程序 用户可以在其中拍照 附加到帖子中 并将图片保存到外部存储中 我希望这张照片也显示在图片库中 并且我正在使用媒体扫描仪意图 但它似乎不起作用 我在编写代码时遵循官方的Android开发人员指南 所以我不
  • 操作错误不会显示在 JSP 上

    我尝试在 Action 类中添加操作错误并将其打印在 JSP 页面上 当发生异常时 它将进入 catch 块并在控制台中打印 插入异常时出错 请联系管理员 在 catch 块中 我添加了它addActionError 我尝试在jsp页面中打
  • 路径中 File.separator 和斜杠之间的区别

    使用有什么区别File separator和一个正常的 在 Java 路径字符串中 与双反斜杠相反 平台独立性似乎不是原因 因为两个版本都可以在 Windows 和 Unix 下运行 public class SlashTest Test
  • 无法解析插件 Java Spring

    我正在使用 IntelliJ IDEA 并且我尝试通过 maven 安装依赖项 但它给了我这些错误 Cannot resolve plugin org apache maven plugins maven clean plugin 3 0
  • 在两个活动之间传输数据[重复]

    这个问题在这里已经有答案了 我正在尝试在两个不同的活动之间发送和接收数据 我在这个网站上看到了一些其他问题 但没有任何问题涉及保留头等舱的状态 例如 如果我想从 A 类发送一个整数 X 到 B 类 然后对整数 X 进行一些操作 然后将其发送
  • 总是使用 Final?

    我读过 将某些东西做成最终的 然后在循环中使用它会带来更好的性能 但这对一切都有好处吗 我有很多地方没有循环 但我将 Final 添加到局部变量中 它会使速度变慢还是仍然很好 还有一些地方我有一个全局变量final 例如android Pa
  • 加密 JBoss 配置中的敏感信息

    JBoss 中的标准数据源配置要求数据库用户的用户名和密码位于 xxx ds xml 文件中 如果我将数据源定义为 c3p0 mbean 我会遇到同样的问题 是否有标准方法来加密用户和密码 保存密钥的好地方是什么 这当然也与 tomcat
  • 如何在 javadoc 中使用“<”和“>”而不进行格式化?

    如果我写
  • 如何在控制器、服务和存储库模式中使用 DTO

    我正在遵循控制器 服务和存储库模式 我只是想知道 DTO 在哪里出现 控制器应该只接收 DTO 吗 我的理解是您不希望外界了解底层域模型 从领域模型到 DTO 的转换应该发生在控制器层还是服务层 在今天使用 Spring MVC 和交互式
  • 在 Mac 上正确运行基于 SWT 的跨平台 jar

    我一直致力于一个基于 SWT 的项目 该项目旨在部署为 Java Web Start 从而可以在多个平台上使用 到目前为止 我已经成功解决了由于 SWT 依赖的系统特定库而出现的导出问题 请参阅相关thread https stackove
  • Java执行器服务线程池[关闭]

    很难说出这里问的是什么 这个问题是含糊的 模糊的 不完整的 过于宽泛的或修辞性的 无法以目前的形式得到合理的回答 如需帮助澄清此问题以便重新打开 访问帮助中心 help reopen questions 如果我使用 Executor 框架在
  • 如何从泛型类调用静态方法?

    我有一个包含静态创建方法的类 public class TestClass public static
  • 在 Maven 依赖项中指定 jar 和 test-jar 类型

    我有一个名为 commons 的项目 其中包含运行时和测试的常见内容 在主项目中 我添加了公共资源的依赖项
  • 将 List 转换为 JSON

    Hi guys 有人可以帮助我 如何将我的 HQL 查询结果转换为带有对象列表的 JSON 并通过休息服务获取它 这是我的服务方法 它返回查询结果列表 Override public List

随机推荐

  • C++:函数左值或右值

    我刚刚开始通过阅读来了解 c 11 中的右值引用这一页 http thbecker net articles rvalue references section 01 html 但我卡在了第一页 这是我从该页面获取的代码 int foo f
  • 熊猫直方图 df.hist() 分组依据

    如何使用 group by 用 pandas DataFrame hist 绘制直方图 我有一个包含 5 列的数据框 A B C D 和 Group 有两个组类别 是 和 否 Using df hist 我获取了 4 列中每一列的历史记录
  • 如何部署经典的asp网站?

    我想知道如何部署或在 IIS 6 7 中部署经典的 asp 网站涉及哪些步骤 我们可以为现有项目创建一个安装程序吗 您应该考虑使用 Web 部署http www iis net download WebDeploy http www iis
  • 如何使用 python apply/lambda/shift 函数根据 2 列的值获取该特定列的前一行值?

    我有 2 列 FN1 和 FN2 基于这些我必须再创建一列 最终 FN1 FN2 Final False False 1 True True 1 False False 1 True False 2 True True 2 False Fa
  • 通过 preg_match_all PHP 函数从 html 代码字符串中提取 img 标签

    我有一些 html 代码并提取了img src来自它的属性 html 字符串中有一些像这样的 img img src http www pecso it wp content uploads 2016 12 10 WRAS png 我尝试使
  • 仅部分页面滚动的 html 布局

    我想创建一个分为 3 部分的页面布局 一列具有固定宽度 其中包含两行具有固定高度 另一个具有固定宽度的列 可能包含多个项目 超出视图范围 我正在寻找一种方法 使页面滚动仅影响项目列 以便屏幕的左侧 第一列 保持在视图中 下面是布局的示例图像
  • SagePay 直接集成套件 v4.00 [关闭]

    Closed 这个问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 是否有适用于 4 00 版本的 Dot Net SagePay 直接集成套件 我试图在 SagePay
  • boost.asio 链接和库

    我是 boost asio 编程的新手 并且在链接 boost 库时遇到困难 我的问题是 当我包含 asio 标头时 如何找出应该链接到我的项目的库 例如我用过 include
  • Paypal PDT交易ID有效期

    当我尝试使用交易 ID 检索付款信息时 我从 paypal PDT 收到错误 4003 虽然我这里有一个类似的线程 贝宝 PDT 错误 4003 https stackoverflow com questions 8521800 paypa
  • bootstrap navbar-static-top 菜单分成两行

    我遇到了引导导航栏的问题 我使用 navbar static top 制作了菜单 起初一切都很好 当菜单被展开并添加了一些项目时 现在随着折叠之前的宽度 它扩展到两行 看起来很糟糕 在 CSS bootstrap 中进行了更深入的挖掘 但没
  • 查明 AD 中的组是否属于通讯组?

    我正在使用 ASP net 和 C 并且对 Active Directory 知之甚少 我接到一项任务 按以下步骤编写程序 ASP net 应用程序被赋予用户的用户名 应用程序应查询具有给定用户名的用户的所有组 然后 应用程序应将这些组显示
  • 使用资源进行主题化,无需 Blend 呕吐

    WPF 的伟大之处在于 我应该能够在整个应用程序中使用 StaticResource MyBackground 而不是 White 然后通过更改资源定义重新定义整个应用程序的外观 问题是如果您在子控件中引用了全局资源 Expression
  • GNU Global 和 GTAGS 找不到类定义

    我在全局查找类 结构定义时遇到问题 我可以使用丰富的 ctags 和 cscope 找到它们 所有标记文件都是从相同的源文件列表构建的 我配置并构建了全局等 仅指定了 prefix configure 确实发现了 exhuberant 并且
  • Anythingslider 触摸滑动功能可阻止 IOS 和平板设备上链接的正常点击

    我正在将任何滑块 jquery 插件与触摸事件一起使用 它似乎在所有设备上都能按预期工作 允许用户通过触摸平板电脑和 iOS 设备以及在桌面上使用鼠标来 滑动 slider anythingSlider Callback when the
  • 使用 volatile 关键字时出现内存一致性错误的示例?

    来自文档 使用易失性变量可以降低内存一致性错误的风险 但这是否意味着有时易失性变量无法正常工作 奇怪的是它的使用方式 在我看来 这是非常糟糕的代码 有时工作有时不工作 我尝试谷歌 但没有找到易失性内存一致性错误的示例 您能推荐一个吗 问题不
  • WordPress > 通过脚本错误设置永久链接选项?

    我的主题的自定义选项面板具有以下代码 初始化站点选项 if get option permalink struct update option permalink struct postname 这会检查永久链接选项设置 并且由于 WP 默
  • 如何在 Xcode 8 中更改应用程序显示名称以添加空格

    我试图在 Xcode 8 中的应用程序名称 独立贴纸包 中添加一个空格 我在这里看到的解决方案是更改产品名称 在包装中 或更改 捆绑显示名称 我更改了产品名称 但没有起作用 我清理 重建 重置模拟器中的内容和设置 并注销 xcode 重新登
  • FileReader 读取 PDF 时丢失数据

    我的限制是只能以 JSON 格式将数据发送到服务器 并且我需要将 PDF 文件与 JSON 中的其他表单数据一起发送 我虽然可以用 base64 从中创建一个字符串 如下所示这个解决方案 https stackoverflow com a
  • apple-app-site-association 从 azure 请求返回为 application/JSON

    我有以下要求 当在 Azure 网站中请求文件的 URL 时 根文件夹中的可用文件必须返回到 application JSON 举例来说 我有一个名为 apple app site association 的文件 它是一个文本文件 在 az
  • 我应该在此 JPQL 查询中包含 unique 吗?

    背景 我在 SO 和许多流行博客中看到了关于必要性的多个答案和问题distinctJPQL 中的关键字JOIN FETCH查询和有关PASS DISTINCT THROUGH查询提示 例如 看这两个问题 使用 JPA 和 Hibernate