【问题标题】:Blank FROM clause in JPQL?JPQL 中的空白 FROM 子句?
【发布时间】:2014-10-30 10:25:16
【问题描述】:

我正在使用 JPQL 选择来访问 Oracle DB 函数:select FUNCTION('function_name', 'foo', 1234) from com_mycompany_bar obj

这按预期工作,并且确实调用了该函数。问题是我实际上不需要 FROM 子句,宁愿让它为空,而不是仅仅为了符合语法而访问实体。

我在这里最好的选择是什么?

【问题讨论】:

  • 我不熟悉 JPQL,但你能不能完全省略 From 子句? select FUNCTION('function_name', 'foo', 1234)?
  • @Siyual 好主意,但不幸的是 JPQL 需要 FROM 子句。

标签: sql jpa jpql


【解决方案1】:

我看到了几个可能的答案:

在标准 JPA 中有两个选项,都涉及 Oracle DUAL "table"

  1. DUAL 映射到一个实体并在FROM 子句中使用它。这是更“JPQL”的方式,但涉及更多:

在 Java 代码中:

@Entity(name = "Dual")
@Table(name = "SYS.DUAL")
public class Dual {
    @Id
    @Column(name = "DUMMY")
    private String dummy;
}

在 orm.xml 中:

<named-query name="yourQuery">
    <query><![CDATA[
        SELECT FUNCTION('function_name', 'foo', 1234) FROM Dual d
    ]]>
    </query>
</named-query>

在客户端代码中:

Query q = entityManager.createNamedQuery("yourQuery");
  1. 只需使用使用DUAL 的本机查询

在 orm.xml 中:

<named-native-query name="yourQuery">
    <query><![CDATA[
        SELECT function_name('foo', 1234) from sys.dual
    ]]>
    </query>
</named-native-query>

在客户端代码中:

Query q = entityManager.createNativeQuery("yourQuery");

作为最后一个选项,您可以使用一些 JPA 实现扩展来 JPA 并避免 DUAL

【讨论】:

  • 很好的解决方案,非常喜欢。
【解决方案2】:

简而言之:我认为不可能跳过 JPQL 查询的 FROM 子句

JPQL 语法要求 FROM 子句必须存在(参见例如herehere)。

调用存储过程/函数通常是通过本机查询完成的(请参阅:createNativeQuery)。所以这应该有效:

em.createNativeQuery("select function_name('foo', 1234)").getSingleResult()

更新(来自 cmets):

JPA 原生查询确实不支持命名参数。所以你必须决定哪一个对你来说是两个弊端中较小的一个:要么使用带有不必要实体引用的 JPQL,要么使用带有位置参数而不是命名的原生查询。

但请注意,FUNCTION 是 EclipseLink 扩展,因此如果您决定更改供应商,它将无法工作。

【讨论】:

  • 我知道可以使用本机查询来做到这一点。 StoredProcedureQuery 不适用于 functions,仅适用于 procedures
  • @Roland 那么是什么原因不能使用原生查询而必须使用 JPQL 查询呢?看来您只是选择了错误的工具来完成这项工作。
  • 本机查询不允许命名参数,只有位置参数。
  • 哦,我明白了。在我看来,您必须选择两个弊端中的较小者:要么使用带有不必要实体引用的 JPQL,要么使用带有位置参数而不是命名的本机查询。 PS。第三个选项是使用(Session)em.getDelegate()(如果您在后台使用Hibernate)并从支持命名参数的Hibernate调用本机查询(请参阅:docs.jboss.org/hibernate/orm/3.3/reference/en/html/…)。但这似乎更糟。
  • 没错。也可以将 DUAL 映射为一个实体(请参阅其他答案),但这看起来有点矫枉过正。
猜你喜欢
  • 2012-09-05
  • 1970-01-01
  • 2021-08-27
  • 1970-01-01
  • 2022-11-08
  • 2020-06-05
  • 1970-01-01
  • 2019-04-20
相关资源
最近更新 更多