Hibernate positional parameters zero based

有些话、适合烂在心里 提交于 2019-12-10 13:28:42

问题


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.


回答1:


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.



来源:https://stackoverflow.com/questions/37973915/hibernate-positional-parameters-zero-based

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!