【问题标题】:JPQL Create new Object In Select Statement - avoid or embrace?JPQL 在 Select 语句中创建新对象 - 避免还是接受?
【发布时间】:2011-01-22 06:43:41
【问题描述】:

我最近了解到,可以在JPQL 语句中创建新对象,如下所示:

select new Family(mother, mate, offspr)
from DomesticCat as mother
    join mother.mate as mate
    left join mother.kittens as offspr

这是应该避免还是应该接受的事情?根据良好做法,何时使用此功能是合理的?

【问题讨论】:

    标签: java hibernate orm jpa jpql


    【解决方案1】:

    不要回避,SELECT NEW 之所以存在,是因为§10.2.7.2 中提醒过它有完全有效的用例。 EJB 3.0 JPA Specification 的 SELECT 子句中的 JPQL 构造函数表达式

    构造函数可以用于 SELECT 列表返回一个或多个 Java 实例。指定的类不是 必须是实体或 映射到数据库。 该 构造函数名称必须是完整的 合格。

    如果指定了实体类名 在 SELECT NEW 子句中, 生成的实体实例在 新状态。

    SELECT NEW com.acme.example.CustomerDetails(c.id, c.status, o.count)
    FROM Customer c JOIN c.orders o
    WHERE o.count > 100
    

    简而言之,当您不想以类型安全的方式(而不是Object[])检索完整实体或对象的完整图时,请使用 SELECT NEW。将查询结果映射到实体类还是非映射类将取决于您的选择。一个典型的例子是列表屏幕(您可能不需要所有详细信息)。

    换句话说,不要到处使用它,但不要禁止它使用(很少有东西只有黑色或白色)。

    【讨论】:

    • 我想做同样的事情,但在我的查询中我有一些 join fetch 和 jpa 抱怨:query specified join fetching, but the owner of the fetched association was not present in the select list。伤心...
    • 请编辑您的答案并将“构造函数名称必须完全限定”加粗。它非常重要,也是常见的错误来源。
    • 答案完全正确,但链接的文档与答案不匹配。应该是jcp.org/aboutJava/communityprocess/final/jsr317/index.html
    • 如果您使用的是static 嵌套类,请使用$,例如SELECT NEW org.soluvas.sanad.core.QuranManager$QuranChapterSummary(c.chapterNum, c.name, c.verseCount) FROM QuranChapter c
    • @Woland 因为查询作为字符串传递给 hibernate/jpa 并且 JPA 不知道查询中的哪个类。你的项目中可以有 10 个 CustomerDetails 类。这就是你告诉 hibernate/jpa 使用哪一个的方式。
    【解决方案2】:

    当您想要检索数据传输对象时,您经常使用这种查询。也许报告可能是使用它的好地方。如果您只想检索单个域对象(例如 from Family),那么没有理由使用它。

    【讨论】:

    • 好点,但您认为 Repository 应该返回 DTO 而不是实体吗?我正在正常转换Service层中的对象,在Repository中是不是太早了?
    【解决方案3】:

    使用 new 创建的 Object 不必是 DTO,即将由业务层导出的 Object。也可以是 POJO Domain Object,即业务层内部使用的 Object。

    使用这种 POJO 作为部分对象而不是完整的 JPA 实体的原因是在特定类型的 JOINS 中的性能。一个很好的资源可以解释这一点:http://use-the-index-luke.com/sql/join/hash-join-partial-objects

    【讨论】:

      猜你喜欢
      • 2012-11-04
      • 2012-12-28
      • 1970-01-01
      • 1970-01-01
      • 2016-11-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多