Blank FROM clause in JPQL?

2019-05-11 14:08发布

问题:

I'm using a JPQL select to access a Oracle DB function: select FUNCTION('function_name', 'foo', 1234) from com_mycompany_bar obj

This works as expected and the function is indeed called. The thing is I actually don't need the FROM clause and would rather have it empty instead of having to access an entity just to conform to the syntax.

What is the best option I have here?

回答1:

I see several possible answers:

Within standard JPA there are two options, both involving Oracle DUAL "table"

  1. Map DUAL to an entity and use it in the FROM clause. It is the more "JPQL" way, but it is more involved:

In Java code:

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

In orm.xml:

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

In client code:

Query q = entityManager.createNamedQuery("yourQuery");
  1. Just use a native query that uses DUAL

In orm.xml:

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

In client code:

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

As a last option, you can use some JPA implementation extension to JPA and avoid DUAL:

  • Eclipselink:

    • http://wiki.eclipse.org/EclipseLink/Examples/JPA/StoredProcedures
    • http://www.eclipse.org/eclipselink/documentation/2.4/jpa/extensions/a_namedstoredprocedurequery.htm
    • http://ronaldoblanc.blogspot.com.br/2012/05/jpa-eclipselink-and-complex-parameters.html
  • Hibernate:

    • http://objectopia.com/2009/06/26/calling-stored-procedures-in-jpa/
    • jpa calling stored procedure with output cursor
    • How to call Oracle Function or Procedure using Hibernate 4 (EntityManager) or JPA 2


回答2:

In short: I don't think it's possible to skip FROM clause of JPQL query.

JPQL grammar requires FROM clause to be present (see e.g. here or here).

Calling stored procedures/functions is typically done via native queries (see: createNativeQuery). So this should work:

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

UPDATE (from comments):

That's true that JPA native queries don't support named parameters. So you must decide which is the lesser of two evils for you: either using JPQL with unnecessary entity reference or native query with positional parameters instead of named.

But be aware that FUNCTION is EclipseLink extension so it won't work should you decide to change a vendor.



标签: sql jpa jpql