Hibernate’s “Pure native scalar queries are not yet supported”
22 April 2012, by: Arjan TijmsIn JPA one can define JPQL queries as well as native queries. Each of those can return either an Entity or one or more scalar values. Queries can be created on demand at run-time from a String, or at start-up time from an annotation (or corresponding XML variant see Where to put named queries in JPA?).
Of all those combinations, curiously Hibernate has never supported named native queries returning a scalar result, including insert, update and delete queries which all don’t return a result set, but merely the number of rows affected.
It’s a curious case, since Hibernate does support scalar returns in non-native named queries (thus a scalar return and named queries is not the problem), and it does support scalar returns in dynamically created native queries (thus scalar returns in native queries are not the problem either).
An example of this specific combination:
<named-native-query name="SomeName"> <query> INSERT INTO foo SELECT * FROM bar </query> </named-native-query>
If you do try to startup with such a query, Hibernate will throw an exception with the notorious message:
Pure native scalar queries are not yet supported
Extra peculiar is that this has been reported as a bug nearly 6 years(!) ago (see HHH-4412). In that timespan the advances in IT have been huge, but apparently not big enough to be able to fix this particular bug. “Not yet” certainly is a relative term in Hibernate’s world.
A quick look at Hibernate’s source-code reveals that the problem is within org.hibernate.cfg.annotations.QueryBinder, more specifically the bindNativeQuery method. It has the following outline:
public static void bindNativeQuery(org.hibernate.annotations.NamedNativeQuery queryAnn, Mappings mappings){ if (BinderHelper.isEmptyAnnotationValue(queryAnn.name())) { throw new AnnotationException("A named query must have a name when used in class or package level"); } NamedSQLQueryDefinition query; String resultSetMapping = queryAnn.resultSetMapping(); if (!BinderHelper.isEmptyAnnotationValue(resultSetMapping)) { query = new NamedSQLQueryDefinition ( // ... ); } else if (!void.class.equals(queryAnn.resultClass())) { // FIXME should be done in a second pass due to entity name? final NativeSQLQueryRootReturn entityQueryReturn = new NativeSQLQueryRootReturn ( // ... ); } else { throw new NotYetImplementedException( "Pure native scalar queries are not yet supported" ); } }
Apparently, the NamedNativeQuery annotation (or corresponding XML version), should either have a non-empty resultset mapping, or a result class that’s something other than void.
So, isn’t a workaround for this problem perhaps to just provide a resultset mapping, even though we’re not doing a select query? To test this, I tried the following:
<named-native-query name="SomeName" result-set-mapping="dummy"> <query> INSERT INTO foo SELECT * FROM bar </query> </named-native-query> <sql-result-set-mapping name="dummy"> <column-result name="bla" /> </sql-result-set-mapping>
And lo and behold, this actually works. Hibernate starts up and adds the query to its named query repository, and when subsequently executing the query there is no exception and the insert happens correctly.
Looking at the Hibernate code again it looks like this shouldn’t be that impossible to fix. It’s almost as if the original programmer just went out for lunch while working on that code fragment, temporarily put the exception there, and then after lunch completely forgot about it.
Until this has been fixed in Hibernate itself, the result-set-mapping workaround might be useful.
Arjan Tijms

23 April, 2012 at 20:35
i owe you one
14 May, 2012 at 20:31
thank you thank you!
27 May, 2012 at 10:21
Thank you so much. I had done the same thing using Annotations but not in XML files. My mistake was to put the tag before .
27 May, 2012 at 10:23
Ops! This ate my XML tags.
In my previous message I simply meant “My mistake was to put the tag <sql-result-set-mapping> before the <named-native-query> tags. Once I moved it below them, it got solved. So thanks
.
27 May, 2012 at 10:38
You’re welcome. Glad it now works for you
12 June, 2012 at 1:03
Hibernate’s “Pure native scalar queries are not yet supported”…
Thank you for submitting this cool story – Trackback from JavaPins…
10 July, 2012 at 14:30
/**
* Simple wrapper entity work around for the limited hibernate pure native query support. Where an HQL query is not possible
*/
@Entity
@NamedNativeQueries({
@NamedNativeQuery(name=”COUNT_QUERY”, resultClass = CountDTO.class)})
public class CountDTO {
@Id
@Column(name = “COUNT”)
private Long count;
public Long getCount() {
return count;
}
public void setCount(Long count) {
this.count = count;
}
}
5 October, 2012 at 13:13
Thanks man.
23 November, 2012 at 9:54
This is great stuff..
Can we do it for stored procedure as well?
7 March, 2013 at 12:12
According to https://hibernate.onjira.com/browse/HHH-4412 this has been fixed on 2013-03-06…
26 April, 2013 at 7:49
Just ran into this right this morning, found your post, avoided a lot of frustration. Thanks.
However, maybe we’ll just upgrade the Hibernate version to see if it works now…