Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Hibernate positional parameters zero based

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

First with Hibernate 4.2.6

@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>

The same with Hibernate 5.2

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.

like image 574
fan Avatar asked Jun 22 '16 16:06

fan


1 Answers

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.

like image 69
Vlad Mihalcea Avatar answered Nov 07 '22 21:11

Vlad Mihalcea