Is HQL still supported in NativeQuery calls in Hibernate 5?

515 views Asked by At

According to latest Hibernate docs section 17.3, this should work:

List<Person> persons = session.createNativeQuery(
        "SELECT * FROM Person", Person.class)
    .getResultList();

I have a nearly identical query and I'm getting an exception:

java.sql.SQLException: Invalid object name 'Person'

I'm using hibernate-core-5.2.10.FINAL. After stepping through the source, it never branches off to look at the entity graph like a normal HQL query does.

Anyone else seeing this? I can post more details for the curious, and will add more stuff as I continue to debug...

I ran the same query after downgrading Hibernate to 5.0.12 with the same result. Although, in Hibernate 5.0 there is no "nativeQuery" method on session, it's "createSQLQuery" which creates a "SQLQuery" object. The Hibernate 5.0 Users Guide section 17.3 says the same though:

List<Person> persons = session.createSQLQuery(
        "SELECT * FROM person" )
    .addEntity( Person.class )
    .list();
1

There are 1 answers

0
ECDragon On

Aha! Answer: No, and HQL was NEVER supported in Hibernate NativeQuery calls.

I misinterpreted the documentation. When I read

("SELECT * FROM Person", Person.class)

...as the arguments for createNativeQuery, I assumed the capitalized "Person" was an entity and would map to whatever table name was specified in Person.class. This is not the case, and never has been the case. The createNativeQuery() method behaves the same as the old createSQLQuery() method, and simply ushers your query string AS IS down to the db, without doing the entity mapping translation stuff on the way down.

The only reason you specify the second class argument is for marshaling ResultSet variables back into an object after the query you gave it is done and has returned results. It's clearer in the old docs with the lowercase "person" in:

"SELECT * FROM person"

...but not real clear, although Hibernate docs are still better than a lot of other libraries' docs.

Anyway, NativeQuery(s) are just like the old SQLQuery(s), and simply execute native sql and try to help you marshal the ResultSet(s).

Oh, and the exception! Why did I get the exception? Because my Person class doesn't map to a table named exactly "Person", so when it tried to execute the query it failed.