I'm migrating a project from Hibernate 4.2.6 to 5.2.0.
I noticed that for Hibernate 5.2.0, the native queries now require zero based parameter positionning.
According to the JPA 2.1 Specification
3.10.13 Positional Parameters
Only positional parameter binding and positional access to result items may be portably used for native queries, except for stored procedure queries for which named parameters have been defined. When binding the values of positional parameters, the numbering starts as “1”. It is assumed that for native queries the parameters themselves use the SQL syntax (i.e., “?”, rather than “?1”).
My understanding of the specification is that even for native queries, the numbering should start with 1.
Now according to Hibernate documentation of Query.setParameter(int, Object). The position is numbered from 0. In the documentation for Hibernate 4.2 as well as for 5.2.
I made a micro test
@PersistenceContext
private EntityManager entityManager;
Query query = entityManager.createNativeQuery("select * from Game g where title = ?");
query.setParameter(1, GAME_TITLES[0]);
List list = query.getResultList();
This works with hibernate 4.2.6.
The persistence.xml file looks like this
<persistence-unit name="test" transaction-type="JTA">
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<jta-data-source>jdbc/arquillian</jta-data-source>
<properties>
<property name="hibernate.dialect" value="org.hibernate.dialect.H2Dialect"/>
<property name="hibernate.hbm2ddl.auto" value="create-drop"/>
</properties>
</persistence-unit>
Query query = entityManager.createNativeQuery("select * from Game g where title = ?");
query.setParameter(0, GAME_TITLES[0]);
List list = query.getResultList();
The only difference is the 0 index in the setParameter.
The persistence.xml is also very similar
<persistence-unit name="test">
<provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
<jta-data-source>jdbc/arquillian</jta-data-source>
<properties>
<property name="hibernate.transaction.jta.platform" value="org.hibernate.service.jta.platform.internal.SunOneJtaPlatform" />
<property name="hibernate.hbm2ddl.auto" value="create-drop"/>
</properties>
</persistence-unit>
I traced the code in both version. I could find in 4.2.6 where the 1 based index is handeled. I could not find a similar code in version 5.2.
I found a post in the hibernate forums dating back to 2009 that:
Well, only if you use the JPA-Query-Api the first parameter must have index = 1. You are using the Hibernate-Query-Api where the first parameter must have index = 0.
Obvioulsy I'm using JPA. So the question is:
Is there a way to configure Hibernate 5.2 to get back the 1 based positional parameter? I would hate to change the code in order not to conform to the specification.
Hibernate 5.2 has merged the hibernate-entitymanager
module into hibernate-core
, so this issue might have occurred in this process.
Since Hibernate 5.2.1 fixed this issue, you just have to upgrade to 5.2.1 or a later version.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With