HHH-10915 - NullPointerException from AbstractProducedQuery.getParameters()
This commit is contained in:
parent
26df5d9e11
commit
5e69823b79
|
@ -51,6 +51,8 @@ import org.hibernate.procedure.spi.ParameterStrategy;
|
||||||
import org.hibernate.procedure.spi.ProcedureCallImplementor;
|
import org.hibernate.procedure.spi.ProcedureCallImplementor;
|
||||||
import org.hibernate.query.QueryParameter;
|
import org.hibernate.query.QueryParameter;
|
||||||
import org.hibernate.query.internal.AbstractProducedQuery;
|
import org.hibernate.query.internal.AbstractProducedQuery;
|
||||||
|
import org.hibernate.query.procedure.internal.ProcedureParameterImpl;
|
||||||
|
import org.hibernate.query.procedure.internal.ProcedureParameterMetadata;
|
||||||
import org.hibernate.result.NoMoreReturnsException;
|
import org.hibernate.result.NoMoreReturnsException;
|
||||||
import org.hibernate.result.Output;
|
import org.hibernate.result.Output;
|
||||||
import org.hibernate.result.ResultSetOutput;
|
import org.hibernate.result.ResultSetOutput;
|
||||||
|
@ -94,7 +96,7 @@ public class ProcedureCallImpl<R>
|
||||||
* @param procedureName The name of the procedure to call
|
* @param procedureName The name of the procedure to call
|
||||||
*/
|
*/
|
||||||
public ProcedureCallImpl(SharedSessionContractImplementor session, String procedureName) {
|
public ProcedureCallImpl(SharedSessionContractImplementor session, String procedureName) {
|
||||||
super( session, null );
|
super( session, new ProcedureParameterMetadata() );
|
||||||
this.procedureName = procedureName;
|
this.procedureName = procedureName;
|
||||||
this.globalParameterPassNullsSetting = session.getFactory().getSessionFactoryOptions().isProcedureParameterNullPassingEnabled();
|
this.globalParameterPassNullsSetting = session.getFactory().getSessionFactoryOptions().isProcedureParameterNullPassingEnabled();
|
||||||
|
|
||||||
|
@ -109,7 +111,7 @@ public class ProcedureCallImpl<R>
|
||||||
* @param resultClasses The classes making up the result
|
* @param resultClasses The classes making up the result
|
||||||
*/
|
*/
|
||||||
public ProcedureCallImpl(final SharedSessionContractImplementor session, String procedureName, Class... resultClasses) {
|
public ProcedureCallImpl(final SharedSessionContractImplementor session, String procedureName, Class... resultClasses) {
|
||||||
super( session, null );
|
super( session, new ProcedureParameterMetadata() );
|
||||||
this.procedureName = procedureName;
|
this.procedureName = procedureName;
|
||||||
this.globalParameterPassNullsSetting = session.getFactory().getSessionFactoryOptions().isProcedureParameterNullPassingEnabled();
|
this.globalParameterPassNullsSetting = session.getFactory().getSessionFactoryOptions().isProcedureParameterNullPassingEnabled();
|
||||||
|
|
||||||
|
@ -148,7 +150,7 @@ public class ProcedureCallImpl<R>
|
||||||
* @param resultSetMappings The names of the result set mappings making up the result
|
* @param resultSetMappings The names of the result set mappings making up the result
|
||||||
*/
|
*/
|
||||||
public ProcedureCallImpl(final SharedSessionContractImplementor session, String procedureName, String... resultSetMappings) {
|
public ProcedureCallImpl(final SharedSessionContractImplementor session, String procedureName, String... resultSetMappings) {
|
||||||
super( session, null );
|
super( session, new ProcedureParameterMetadata() );
|
||||||
this.procedureName = procedureName;
|
this.procedureName = procedureName;
|
||||||
this.globalParameterPassNullsSetting = session.getFactory().getSessionFactoryOptions().isProcedureParameterNullPassingEnabled();
|
this.globalParameterPassNullsSetting = session.getFactory().getSessionFactoryOptions().isProcedureParameterNullPassingEnabled();
|
||||||
|
|
||||||
|
@ -192,7 +194,7 @@ public class ProcedureCallImpl<R>
|
||||||
*/
|
*/
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
ProcedureCallImpl(SharedSessionContractImplementor session, ProcedureCallMementoImpl memento) {
|
ProcedureCallImpl(SharedSessionContractImplementor session, ProcedureCallMementoImpl memento) {
|
||||||
super( session, null );
|
super( session, new ProcedureParameterMetadata() );
|
||||||
this.procedureName = memento.getProcedureName();
|
this.procedureName = memento.getProcedureName();
|
||||||
this.globalParameterPassNullsSetting = session.getFactory().getSessionFactoryOptions().isProcedureParameterNullPassingEnabled();
|
this.globalParameterPassNullsSetting = session.getFactory().getSessionFactoryOptions().isProcedureParameterNullPassingEnabled();
|
||||||
|
|
||||||
|
@ -250,6 +252,7 @@ public class ProcedureCallImpl<R>
|
||||||
storedRegistration.isPassNullsEnabled()
|
storedRegistration.isPassNullsEnabled()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
getParameterMetadata().registerParameter( new ProcedureParameterImpl( registration ) );
|
||||||
parameterRegistrations.add( registration );
|
parameterRegistrations.add( registration );
|
||||||
}
|
}
|
||||||
this.registeredParameters = parameterRegistrations;
|
this.registeredParameters = parameterRegistrations;
|
||||||
|
@ -259,6 +262,11 @@ public class ProcedureCallImpl<R>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ProcedureParameterMetadata getParameterMetadata() {
|
||||||
|
return (ProcedureParameterMetadata) super.getParameterMetadata();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public SharedSessionContractImplementor getSession() {
|
public SharedSessionContractImplementor getSession() {
|
||||||
return getProducer();
|
return getProducer();
|
||||||
|
@ -286,6 +294,7 @@ public class ProcedureCallImpl<R>
|
||||||
@Override
|
@Override
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
public <T> ParameterRegistration<T> registerParameter(int position, Class<T> type, ParameterMode mode) {
|
public <T> ParameterRegistration<T> registerParameter(int position, Class<T> type, ParameterMode mode) {
|
||||||
|
|
||||||
final PositionalParameterRegistration parameterRegistration =
|
final PositionalParameterRegistration parameterRegistration =
|
||||||
new PositionalParameterRegistration( this, position, mode, type, globalParameterPassNullsSetting );
|
new PositionalParameterRegistration( this, position, mode, type, globalParameterPassNullsSetting );
|
||||||
registerParameter( parameterRegistration );
|
registerParameter( parameterRegistration );
|
||||||
|
@ -309,6 +318,8 @@ public class ProcedureCallImpl<R>
|
||||||
else {
|
else {
|
||||||
throw new IllegalArgumentException( "Given parameter did not define name or position [" + parameter + "]" );
|
throw new IllegalArgumentException( "Given parameter did not define name or position [" + parameter + "]" );
|
||||||
}
|
}
|
||||||
|
((ProcedureParameterMetadata)getParameterMetadata()).registerParameter( new ProcedureParameterImpl( parameter ) );
|
||||||
|
|
||||||
registeredParameters.add( parameter );
|
registeredParameters.add( parameter );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -44,6 +44,7 @@ import org.hibernate.LockMode;
|
||||||
import org.hibernate.LockOptions;
|
import org.hibernate.LockOptions;
|
||||||
import org.hibernate.NonUniqueResultException;
|
import org.hibernate.NonUniqueResultException;
|
||||||
import org.hibernate.PropertyNotFoundException;
|
import org.hibernate.PropertyNotFoundException;
|
||||||
|
import org.hibernate.QueryParameterException;
|
||||||
import org.hibernate.ScrollMode;
|
import org.hibernate.ScrollMode;
|
||||||
import org.hibernate.TypeMismatchException;
|
import org.hibernate.TypeMismatchException;
|
||||||
import org.hibernate.engine.query.spi.EntityGraphQueryHint;
|
import org.hibernate.engine.query.spi.EntityGraphQueryHint;
|
||||||
|
@ -617,13 +618,13 @@ public abstract class AbstractProducedQuery<R> implements QueryImplementor<R> {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Set<Parameter<?>> getParameters() {
|
public Set<Parameter<?>> getParameters() {
|
||||||
return parameterMetadata.collectAllParametersJpa();
|
return getParameterMetadata().collectAllParametersJpa();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Parameter<?> getParameter(String name) {
|
public Parameter<?> getParameter(String name) {
|
||||||
try {
|
try {
|
||||||
return parameterMetadata.getQueryParameter( name );
|
return getParameterMetadata().getQueryParameter( name );
|
||||||
}
|
}
|
||||||
catch ( HibernateException e ) {
|
catch ( HibernateException e ) {
|
||||||
throw getExceptionConverter().convert( e );
|
throw getExceptionConverter().convert( e );
|
||||||
|
@ -634,7 +635,7 @@ public abstract class AbstractProducedQuery<R> implements QueryImplementor<R> {
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
public <T> Parameter<T> getParameter(String name, Class<T> type) {
|
public <T> Parameter<T> getParameter(String name, Class<T> type) {
|
||||||
try {
|
try {
|
||||||
final QueryParameter parameter = parameterMetadata.getQueryParameter( name );
|
final QueryParameter parameter = getParameterMetadata().getQueryParameter( name );
|
||||||
if ( !parameter.getParameterType().isAssignableFrom( type ) ) {
|
if ( !parameter.getParameterType().isAssignableFrom( type ) ) {
|
||||||
throw new IllegalArgumentException(
|
throw new IllegalArgumentException(
|
||||||
"The type [" + parameter.getParameterType().getName() +
|
"The type [" + parameter.getParameterType().getName() +
|
||||||
|
@ -657,20 +658,25 @@ public abstract class AbstractProducedQuery<R> implements QueryImplementor<R> {
|
||||||
// deprecated since 5.x. These are numbered starting from 0 and kept in the
|
// deprecated since 5.x. These are numbered starting from 0 and kept in the
|
||||||
// ParameterMetadata positional-parameter array keyed by this zero-based position
|
// ParameterMetadata positional-parameter array keyed by this zero-based position
|
||||||
// 2) JPA's definition is really just a named parameter, but expected to explicitly be
|
// 2) JPA's definition is really just a named parameter, but expected to explicitly be
|
||||||
// sequential intergers starting from 0 (ZERO); they can repeat.
|
// sequential integers starting from 1 (ONE); they can repeat.
|
||||||
//
|
//
|
||||||
// It is considered illegal to mix positional-parameter with named parameters of any kind. So therefore.
|
// It is considered illegal to mix positional-parameter with named parameters of any kind. So therefore.
|
||||||
// if ParameterMetadata reports that it has any positional-parameters it is talking about the
|
// if ParameterMetadata reports that it has any positional-parameters it is talking about the
|
||||||
// legacy Hibernate concept.
|
// legacy Hibernate concept.
|
||||||
// lookup jpa-based positional parameters first by name.
|
// lookup jpa-based positional parameters first by name.
|
||||||
try {
|
try {
|
||||||
if ( parameterMetadata.getPositionalParameterCount() == 0 ) {
|
if ( getParameterMetadata().getPositionalParameterCount() == 0 ) {
|
||||||
return parameterMetadata.getQueryParameter( Integer.toString( position ) );
|
try {
|
||||||
|
return getParameterMetadata().getQueryParameter( Integer.toString( position ) );
|
||||||
}
|
}
|
||||||
// fallback to oridinal lookup
|
catch (HibernateException e) {
|
||||||
return parameterMetadata.getQueryParameter( position );
|
throw new QueryParameterException( "could not locate parameter at position [" + position + "]" );
|
||||||
}
|
}
|
||||||
catch ( HibernateException e ) {
|
}
|
||||||
|
// fallback to ordinal lookup
|
||||||
|
return getParameterMetadata().getQueryParameter( position );
|
||||||
|
}
|
||||||
|
catch (HibernateException e) {
|
||||||
throw getExceptionConverter().convert( e );
|
throw getExceptionConverter().convert( e );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -679,7 +685,7 @@ public abstract class AbstractProducedQuery<R> implements QueryImplementor<R> {
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
public <T> Parameter<T> getParameter(int position, Class<T> type) {
|
public <T> Parameter<T> getParameter(int position, Class<T> type) {
|
||||||
try {
|
try {
|
||||||
final QueryParameter parameter = parameterMetadata.getQueryParameter( position );
|
final QueryParameter parameter = getParameterMetadata().getQueryParameter( position );
|
||||||
if ( !parameter.getParameterType().isAssignableFrom( type ) ) {
|
if ( !parameter.getParameterType().isAssignableFrom( type ) ) {
|
||||||
throw new IllegalArgumentException(
|
throw new IllegalArgumentException(
|
||||||
"The type [" + parameter.getParameterType().getName() +
|
"The type [" + parameter.getParameterType().getName() +
|
||||||
|
@ -750,7 +756,7 @@ public abstract class AbstractProducedQuery<R> implements QueryImplementor<R> {
|
||||||
protected Type determineType(String namedParam, Class retType) {
|
protected Type determineType(String namedParam, Class retType) {
|
||||||
Type type = queryParameterBindings.getBinding( namedParam ).getBindType();
|
Type type = queryParameterBindings.getBinding( namedParam ).getBindType();
|
||||||
if ( type == null ) {
|
if ( type == null ) {
|
||||||
type = parameterMetadata.getQueryParameter( namedParam ).getType();
|
type = getParameterMetadata().getQueryParameter( namedParam ).getType();
|
||||||
}
|
}
|
||||||
if ( type == null ) {
|
if ( type == null ) {
|
||||||
type = getProducer().getFactory().resolveParameterBindType( retType );
|
type = getProducer().getFactory().resolveParameterBindType( retType );
|
||||||
|
|
|
@ -13,6 +13,7 @@ import java.util.List;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import javax.persistence.Parameter;
|
import javax.persistence.Parameter;
|
||||||
|
|
||||||
|
import org.hibernate.QueryParameterException;
|
||||||
import org.hibernate.query.ParameterMetadata;
|
import org.hibernate.query.ParameterMetadata;
|
||||||
import org.hibernate.query.QueryParameter;
|
import org.hibernate.query.QueryParameter;
|
||||||
import org.hibernate.query.procedure.ProcedureParameter;
|
import org.hibernate.query.procedure.ProcedureParameter;
|
||||||
|
@ -27,6 +28,10 @@ public class ProcedureParameterMetadata implements ParameterMetadata {
|
||||||
private boolean hasNamed;
|
private boolean hasNamed;
|
||||||
private int ordinalParamCount;
|
private int ordinalParamCount;
|
||||||
|
|
||||||
|
public ProcedureParameterMetadata() {
|
||||||
|
parameters = new ArrayList<>( );
|
||||||
|
}
|
||||||
|
|
||||||
public void registerParameter(ProcedureParameterImplementor parameter) {
|
public void registerParameter(ProcedureParameterImplementor parameter) {
|
||||||
if ( parameters == null ) {
|
if ( parameters == null ) {
|
||||||
parameters = new ArrayList<>();
|
parameters = new ArrayList<>();
|
||||||
|
@ -91,16 +96,19 @@ public class ProcedureParameterMetadata implements ParameterMetadata {
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
public <T> QueryParameter<T> getQueryParameter(String name) {
|
public <T> QueryParameter<T> getQueryParameter(String name) {
|
||||||
assert name != null;
|
assert name != null;
|
||||||
|
QueryParameter<T> result = null;
|
||||||
if ( hasNamed ) {
|
if ( hasNamed ) {
|
||||||
for ( ProcedureParameter parameter : parameters ) {
|
for ( ProcedureParameter parameter : parameters ) {
|
||||||
if ( name.equals( parameter.getName() ) ) {
|
if ( name.equals( parameter.getName() ) ) {
|
||||||
return parameter;
|
result = parameter;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if ( result != null ) {
|
||||||
return null;
|
return result;
|
||||||
|
}
|
||||||
|
throw new QueryParameterException( "could not locate named parameter [" + name + "]" );
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -115,8 +123,7 @@ public class ProcedureParameterMetadata implements ParameterMetadata {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
throw new QueryParameterException( "could not locate parameter at position [" + position + "]" );
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -0,0 +1,159 @@
|
||||||
|
/*
|
||||||
|
* Hibernate, Relational Persistence for Idiomatic Java
|
||||||
|
*
|
||||||
|
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
|
||||||
|
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
|
||||||
|
*/
|
||||||
|
package org.hibernate.jpa.test.procedure;
|
||||||
|
|
||||||
|
import javax.persistence.Entity;
|
||||||
|
import javax.persistence.EntityManager;
|
||||||
|
import javax.persistence.Id;
|
||||||
|
import javax.persistence.Parameter;
|
||||||
|
import javax.persistence.ParameterMode;
|
||||||
|
import javax.persistence.StoredProcedureQuery;
|
||||||
|
import javax.persistence.Table;
|
||||||
|
import java.sql.Connection;
|
||||||
|
import java.sql.ResultSet;
|
||||||
|
import java.sql.SQLException;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import org.hibernate.dialect.H2Dialect;
|
||||||
|
import org.hibernate.jpa.test.BaseEntityManagerFunctionalTestCase;
|
||||||
|
|
||||||
|
import org.junit.After;
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import org.hibernate.testing.RequiresDialect;
|
||||||
|
|
||||||
|
import static org.hamcrest.core.Is.is;
|
||||||
|
import static org.hamcrest.core.IsNot.not;
|
||||||
|
import static org.hamcrest.core.IsNull.nullValue;
|
||||||
|
import static org.junit.Assert.assertThat;
|
||||||
|
import static org.junit.Assert.fail;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Andrea Boriero
|
||||||
|
*/
|
||||||
|
@RequiresDialect(H2Dialect.class)
|
||||||
|
public class H2StoreProcedureTest extends BaseEntityManagerFunctionalTestCase {
|
||||||
|
@Override
|
||||||
|
protected Class<?>[] getAnnotatedClasses() {
|
||||||
|
return new Class<?>[] {MyEntity.class};
|
||||||
|
}
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void setUp() {
|
||||||
|
final EntityManager entityManager = getOrCreateEntityManager();
|
||||||
|
try {
|
||||||
|
entityManager.getTransaction().begin();
|
||||||
|
entityManager.createNativeQuery( "CREATE ALIAS get_all_entities FOR \"" + H2StoreProcedureTest.class.getCanonicalName() + ".getAllEntities\";" )
|
||||||
|
.executeUpdate();
|
||||||
|
|
||||||
|
entityManager.createNativeQuery( "CREATE ALIAS by_id FOR \"" + H2StoreProcedureTest.class.getCanonicalName() + ".entityById\";" )
|
||||||
|
.executeUpdate();
|
||||||
|
MyEntity entity = new MyEntity();
|
||||||
|
entity.id = 1;
|
||||||
|
entity.name = "entity1";
|
||||||
|
entityManager.persist( entity );
|
||||||
|
|
||||||
|
entityManager.getTransaction().commit();
|
||||||
|
|
||||||
|
}
|
||||||
|
catch (Exception e) {
|
||||||
|
if ( entityManager.getTransaction().isActive() ) {
|
||||||
|
entityManager.getTransaction().rollback();
|
||||||
|
}
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
finally {
|
||||||
|
entityManager.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@After
|
||||||
|
public void tearDown() {
|
||||||
|
final EntityManager entityManager = getOrCreateEntityManager();
|
||||||
|
try {
|
||||||
|
entityManager.getTransaction().begin();
|
||||||
|
entityManager.createNativeQuery( "DROP ALIAS IF EXISTS get_all_entities" ).executeUpdate();
|
||||||
|
entityManager.createNativeQuery( "DROP ALIAS IF EXISTS by_id" ).executeUpdate();
|
||||||
|
entityManager.getTransaction().commit();
|
||||||
|
}
|
||||||
|
catch (Exception e) {
|
||||||
|
if ( entityManager.getTransaction().isActive() ) {
|
||||||
|
entityManager.getTransaction().rollback();
|
||||||
|
}
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
finally {
|
||||||
|
entityManager.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ResultSet getAllEntities(Connection conn) throws SQLException {
|
||||||
|
return conn.createStatement().executeQuery( "select * from MY_ENTITY" );
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ResultSet entityById(Connection conn, long id) throws SQLException {
|
||||||
|
return conn.createStatement().executeQuery( "select * from MY_ENTITY where id = " + Long.toString( id ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testStoreProcedureGetParameters() {
|
||||||
|
final EntityManager entityManager = getOrCreateEntityManager();
|
||||||
|
try {
|
||||||
|
StoredProcedureQuery query = entityManager.createStoredProcedureQuery( "get_all_entities", MyEntity.class );
|
||||||
|
final Set<Parameter<?>> parameters = query.getParameters();
|
||||||
|
assertThat( parameters.size(), is( 0 ) );
|
||||||
|
|
||||||
|
final List resultList = query.getResultList();
|
||||||
|
assertThat( resultList.size(), is( 1 ) );
|
||||||
|
}
|
||||||
|
finally {
|
||||||
|
entityManager.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testStoreProcedureGetParameterByPosition() {
|
||||||
|
final EntityManager entityManager = getOrCreateEntityManager();
|
||||||
|
try {
|
||||||
|
StoredProcedureQuery query = entityManager.createStoredProcedureQuery( "by_Id", MyEntity.class );
|
||||||
|
query.registerStoredProcedureParameter( 1, Long.class, ParameterMode.IN );
|
||||||
|
|
||||||
|
query.setParameter( 1, 1L );
|
||||||
|
|
||||||
|
final List resultList = query.getResultList();
|
||||||
|
assertThat( resultList.size(), is( 1 ) );
|
||||||
|
|
||||||
|
final Set<Parameter<?>> parameters = query.getParameters();
|
||||||
|
assertThat( parameters.size(), is( 1 ) );
|
||||||
|
|
||||||
|
final Parameter<?> parameter = query.getParameter( 1 );
|
||||||
|
assertThat( parameter, not( nullValue() ) );
|
||||||
|
|
||||||
|
try {
|
||||||
|
query.getParameter( 2 );
|
||||||
|
fail( "IllegalArgumentException expected, parameter at position 2 does not exist" );
|
||||||
|
}
|
||||||
|
catch (IllegalArgumentException iae) {
|
||||||
|
//expected
|
||||||
|
}
|
||||||
|
}
|
||||||
|
finally {
|
||||||
|
entityManager.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Entity(name = "MyEntity")
|
||||||
|
@Table(name = "MY_ENTITY")
|
||||||
|
public static class MyEntity {
|
||||||
|
@Id
|
||||||
|
long id;
|
||||||
|
|
||||||
|
String name;
|
||||||
|
}
|
||||||
|
}
|
|
@ -11,7 +11,9 @@ import javax.persistence.EntityManager;
|
||||||
import javax.persistence.EntityManagerFactory;
|
import javax.persistence.EntityManagerFactory;
|
||||||
import javax.persistence.GeneratedValue;
|
import javax.persistence.GeneratedValue;
|
||||||
import javax.persistence.Id;
|
import javax.persistence.Id;
|
||||||
|
import javax.persistence.NamedStoredProcedureQueries;
|
||||||
import javax.persistence.NamedStoredProcedureQuery;
|
import javax.persistence.NamedStoredProcedureQuery;
|
||||||
|
import javax.persistence.Parameter;
|
||||||
import javax.persistence.ParameterMode;
|
import javax.persistence.ParameterMode;
|
||||||
import javax.persistence.StoredProcedureParameter;
|
import javax.persistence.StoredProcedureParameter;
|
||||||
import javax.persistence.StoredProcedureQuery;
|
import javax.persistence.StoredProcedureQuery;
|
||||||
|
@ -19,6 +21,7 @@ import javax.persistence.Table;
|
||||||
import java.sql.Connection;
|
import java.sql.Connection;
|
||||||
import java.sql.SQLException;
|
import java.sql.SQLException;
|
||||||
import java.sql.Statement;
|
import java.sql.Statement;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
import org.hibernate.dialect.HSQLDialect;
|
import org.hibernate.dialect.HSQLDialect;
|
||||||
import org.hibernate.engine.jdbc.connections.spi.JdbcConnectionAccess;
|
import org.hibernate.engine.jdbc.connections.spi.JdbcConnectionAccess;
|
||||||
|
@ -27,18 +30,22 @@ import org.hibernate.engine.spi.SessionFactoryImplementor;
|
||||||
import org.hibernate.jpa.test.BaseEntityManagerFunctionalTestCase;
|
import org.hibernate.jpa.test.BaseEntityManagerFunctionalTestCase;
|
||||||
|
|
||||||
import org.junit.After;
|
import org.junit.After;
|
||||||
|
import org.junit.Assert;
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
import org.hibernate.testing.RequiresDialect;
|
import org.hibernate.testing.RequiresDialect;
|
||||||
import org.hibernate.testing.TestForIssue;
|
import org.hibernate.testing.TestForIssue;
|
||||||
|
|
||||||
|
import static org.hamcrest.MatcherAssert.assertThat;
|
||||||
|
import static org.hamcrest.core.Is.is;
|
||||||
|
import static org.hamcrest.core.IsNot.not;
|
||||||
|
import static org.hamcrest.core.IsNull.nullValue;
|
||||||
import static org.junit.Assert.fail;
|
import static org.junit.Assert.fail;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Andrea Boriero
|
* @author Andrea Boriero
|
||||||
*/
|
*/
|
||||||
@TestForIssue(jiraKey = "HHH-10515")
|
|
||||||
@RequiresDialect(value = HSQLDialect.class)
|
@RequiresDialect(value = HSQLDialect.class)
|
||||||
public class HSQLStoreProcedureTest extends BaseEntityManagerFunctionalTestCase {
|
public class HSQLStoreProcedureTest extends BaseEntityManagerFunctionalTestCase {
|
||||||
EntityManagerFactory entityManagerFactory;
|
EntityManagerFactory entityManagerFactory;
|
||||||
|
@ -61,6 +68,7 @@ public class HSQLStoreProcedureTest extends BaseEntityManagerFunctionalTestCase
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@TestForIssue(jiraKey = "HHH-10515")
|
||||||
public void testNamedStoredProcedureExecution() {
|
public void testNamedStoredProcedureExecution() {
|
||||||
EntityManager em = entityManagerFactory.createEntityManager();
|
EntityManager em = entityManagerFactory.createEntityManager();
|
||||||
try {
|
try {
|
||||||
|
@ -73,6 +81,99 @@ public class HSQLStoreProcedureTest extends BaseEntityManagerFunctionalTestCase
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestForIssue(jiraKey = "HHH-10915")
|
||||||
|
public void testGetNamedParameters() {
|
||||||
|
EntityManager em = entityManagerFactory.createEntityManager();
|
||||||
|
try {
|
||||||
|
StoredProcedureQuery query = em.createNamedStoredProcedureQuery( "User.inoutproc" );
|
||||||
|
final Set<Parameter<?>> parameters = query.getParameters();
|
||||||
|
assertThat( parameters.size(), is( 2 ) );
|
||||||
|
assertThat( query.getParameter( "arg1" ), not( nullValue() ) );
|
||||||
|
assertThat( query.getParameter( "res" ), not( nullValue() ) );
|
||||||
|
assertThat( query.getParameter( "arg1", Integer.class ), not( nullValue() ) );
|
||||||
|
try {
|
||||||
|
query.getParameter( "arg1", String.class );
|
||||||
|
fail( "An IllegalArgumentException is expected, A parameter with name arg1 and type String does not exist" );
|
||||||
|
}
|
||||||
|
catch (IllegalArgumentException iae) {
|
||||||
|
//expected
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
query.getParameter( "arg2" );
|
||||||
|
fail( "An IllegalArgumentException is expected, A parameter with name arg2 does not exist" );
|
||||||
|
}
|
||||||
|
catch (IllegalArgumentException iae) {
|
||||||
|
//expected
|
||||||
|
}
|
||||||
|
}
|
||||||
|
finally {
|
||||||
|
em.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestForIssue(jiraKey = "HHH-10915")
|
||||||
|
public void testGetPositionalParameters() {
|
||||||
|
EntityManager em = entityManagerFactory.createEntityManager();
|
||||||
|
try {
|
||||||
|
StoredProcedureQuery query = em.createNamedStoredProcedureQuery( "User.inoutproc" );
|
||||||
|
final Set<Parameter<?>> parameters = query.getParameters();
|
||||||
|
assertThat( parameters.size(), is( 2 ) );
|
||||||
|
try {
|
||||||
|
query.getParameter( 1 );
|
||||||
|
fail( "An IllegalArgumentException is expected, The stored procedure has named parameters not positional" );
|
||||||
|
}
|
||||||
|
catch (IllegalArgumentException iae) {
|
||||||
|
//expected
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
query.getParameter( 1, String.class );
|
||||||
|
fail( "An IllegalArgumentException is expected, The stored procedure has named parameters not positional" );
|
||||||
|
}
|
||||||
|
catch (IllegalArgumentException iae) {
|
||||||
|
//expected
|
||||||
|
}
|
||||||
|
}
|
||||||
|
finally {
|
||||||
|
em.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestForIssue(jiraKey = "HHH-10915")
|
||||||
|
public void testGetPositionalParameters2() {
|
||||||
|
EntityManager em = entityManagerFactory.createEntityManager();
|
||||||
|
try {
|
||||||
|
StoredProcedureQuery query = em.createNamedStoredProcedureQuery( "User.inoutprocpositional" );
|
||||||
|
final Set<Parameter<?>> parameters = query.getParameters();
|
||||||
|
assertThat( parameters.size(), is( 2 ) );
|
||||||
|
assertThat( query.getParameter( 1 ), not( nullValue() ) );
|
||||||
|
assertThat( query.getParameter( 2 ), not( nullValue() ) );
|
||||||
|
assertThat( query.getParameter( 1, Integer.class ), not( nullValue() ) );
|
||||||
|
try {
|
||||||
|
query.getParameter( 3 );
|
||||||
|
fail( "An IllegalArgumentException is expected, A parameter at position 3 does not exist" );
|
||||||
|
}
|
||||||
|
catch (IllegalArgumentException iae) {
|
||||||
|
//expected
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
query.getParameter( 1, String.class );
|
||||||
|
fail( "An IllegalArgumentException is expected, The parameter at position 1 is of type Integer not String" );
|
||||||
|
}
|
||||||
|
catch (IllegalArgumentException iae) {
|
||||||
|
//expected
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
finally {
|
||||||
|
em.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void createProcedures(EntityManagerFactory emf) {
|
private void createProcedures(EntityManagerFactory emf) {
|
||||||
final String procedureStatement = "CREATE procedure inoutproc (IN arg1 int, OUT res int) " +
|
final String procedureStatement = "CREATE procedure inoutproc (IN arg1 int, OUT res int) " +
|
||||||
"BEGIN ATOMIC set res = arg1 + 1;" +
|
"BEGIN ATOMIC set res = arg1 + 1;" +
|
||||||
|
@ -127,10 +228,18 @@ public class HSQLStoreProcedureTest extends BaseEntityManagerFunctionalTestCase
|
||||||
}
|
}
|
||||||
|
|
||||||
@Entity(name = "User")
|
@Entity(name = "User")
|
||||||
|
@NamedStoredProcedureQueries(value = {
|
||||||
@NamedStoredProcedureQuery(name = "User.inoutproc", procedureName = "inoutproc", parameters = {
|
@NamedStoredProcedureQuery(name = "User.inoutproc", procedureName = "inoutproc", parameters = {
|
||||||
@StoredProcedureParameter(mode = ParameterMode.IN, name = "arg1", type = Integer.class),
|
@StoredProcedureParameter(mode = ParameterMode.IN, name = "arg1", type = Integer.class),
|
||||||
@StoredProcedureParameter(mode = ParameterMode.OUT, name = "res", type = Integer.class)
|
@StoredProcedureParameter(mode = ParameterMode.OUT, name = "res", type = Integer.class)
|
||||||
})
|
})
|
||||||
|
,
|
||||||
|
@NamedStoredProcedureQuery(name = "User.inoutprocpositional", procedureName = "inoutproc", parameters = {
|
||||||
|
@StoredProcedureParameter(mode = ParameterMode.IN, type = Integer.class),
|
||||||
|
@StoredProcedureParameter(mode = ParameterMode.OUT, type = Integer.class)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
)
|
||||||
@Table(name = "USERS")
|
@Table(name = "USERS")
|
||||||
public class User {
|
public class User {
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue