NumericBooleanType hibernate type cannot bind value in StoredProcedureQuery

Hi all,

I tried to call a procedure with Hibernate ORM 5.3.0.Final, then I got an IllegalArgumentException.
Example code:

inTransaction(
				session -> {
					final StoredProcedureQuery procedureQuery = session.createStoredProcedureQuery( "test" );

					procedureQuery.registerStoredProcedureParameter(1, NumericBooleanType.class, ParameterMode.IN);
					procedureQuery.setParameter( 1, false );
				}
		);

Exception:

**java.lang.IllegalArgumentException: Bind value [false] was not of specified type [class org.hibernate.type.NumericBooleanType**
	at org.hibernate.procedure.internal.ParameterBindImpl.internalSetValue(ParameterBindImpl.java:83)
	at org.hibernate.procedure.internal.ParameterBindImpl.setBindValue(ParameterBindImpl.java:64)
	at org.hibernate.procedure.internal.ProcedureCallImpl.setParameter(ProcedureCallImpl.java:818)
	at org.hibernate.procedure.internal.ProcedureCallImpl.setParameter(ProcedureCallImpl.java:70)

Could you help me for this issue?

Best Regards
Roland

Change this:

procedureQuery.registerStoredProcedureParameter(1, NumericBooleanType.class, ParameterMode.IN);

to this:

procedureQuery.registerStoredProcedureParameter(1, Boolean.class, ParameterMode.IN);

The type parameter is the Java Type of the parameter and has nothing to do with Hibernate Types.

This NumericBooleanType works in the previous Hibernate version 5.2.
What about the YesNoType? The result of it is the same exception.
How can I use my own implementations of UserType?

This is how the type is passed on:

public <T> ParameterRegistration<T> registerParameter(int position, Class<T> type, ParameterMode mode) {
	final ProcedureParameterImpl procedureParameter = new ProcedureParameterImpl(
			this,
			position,
			mode,
			type,
			getSession().getFactory().getTypeResolver().heuristicType( type.getName() ),
			globalParameterPassNullsSetting
	);

	registerParameter( procedureParameter );
	return procedureParameter;
}

Notice that you have both the type and the hibernateType. Theoretically, you could use a custom Type as well. Just try it and see where it breaks.

Better build up a test case as it’s going to be easier to implement a fix if it turns out to be an issue in hibernate-core.

In my opinion, the backward compatibility is most important.
Please give me a solution, how can I use the YesNoType in a StoredProcedureQuery.

I have debugged the codes in hibernate-core. The implementation of ParameterRegistration was changed.
The implementations of ParameterRegistration in Hibenate 5.2:
NamedParameterRegistration:

	@Override
	@SuppressWarnings("unchecked")
	public <T> ParameterRegistration<T> registerParameter(String name, Class<T> type, ParameterMode mode) {
		final NamedParameterRegistration parameterRegistration = new NamedParameterRegistration( this, name, mode, type, globalParameterPassNullsSetting );
		registerParameter( parameterRegistration );
		return parameterRegistration;
	}

PositionalParameterRegistration:

	@Override
	@SuppressWarnings("unchecked")
	public <T> ParameterRegistration<T> registerParameter(int position, Class<T> type, ParameterMode mode) {

		final PositionalParameterRegistration parameterRegistration =
				new PositionalParameterRegistration( this, position, mode, type, globalParameterPassNullsSetting );
		registerParameter( parameterRegistration );
		return parameterRegistration;
	}

The implementation was changed at this commit: https://github.com/hibernate/hibernate-orm/commit/6ba328e7a03d2faaf648e85310e903f11211cbd8

Better build up a test case as it’s going to be easier to implement a fix if it turns out to be an issue in hibernate-core.

1 Like

Please perform these tests with Hibernate 5.2 and 5.3.

package com.example;

import org.hibernate.Session;
import org.hibernate.dialect.H2Dialect;
import org.hibernate.testing.RequiresDialect;
import org.hibernate.testing.junit4.BaseNonConfigCoreFunctionalTestCase;
import org.hibernate.type.NumericBooleanType;
import org.hibernate.type.YesNoType;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;

import javax.persistence.ParameterMode;

@RequiresDialect(H2Dialect.class)
public class StoredProcedureApiTest extends BaseNonConfigCoreFunctionalTestCase {

    private Session session;

    @Before
    public void setUp() {
        session = openSession();
    }

    @After
    public void tearDown() {
        session.close();
    }


    @Test
    public void testNumericBooleanTypeInParameter() {
        session.createStoredProcedureQuery("test")
                .registerStoredProcedureParameter(1, NumericBooleanType.class, ParameterMode.IN)
                .registerStoredProcedureParameter(2, String.class, ParameterMode.OUT)
                .setParameter(1, false);
    }

    @Test
    public void testYesNoTypeInParameter() {
        session.createStoredProcedureQuery("test")
                .registerStoredProcedureParameter(1, YesNoType.class, ParameterMode.IN)
                .registerStoredProcedureParameter(2, String.class, ParameterMode.OUT)
                .setParameter(1, false);
    }

}

Great. Please send it as a Pull Request as explained in this article.

Thanks the information.

I have created an issue about this problem in the Hibernate Issue System

https://hibernate.atlassian.net/browse/HHH-12661

The test cases are coming soon.

Thanks. I can do the test as I wanted to have one for Oracle which does not support a true boolean type anyway.

I submitted a Pull Request. If it’s approved, we can have it in the next 5.3.x release.

Thank you very much.

I have added a Pull Request with some tests: https://github.com/hibernate/hibernate-orm/pull/2327

I hope It is not problem.

Thanks. I’ll review it tomorrow.