HHH-9548 - Allow propagation of NULL for stored-procedure argument parameters to database
This commit is contained in:
parent
19d86c3d65
commit
13bbddfd30
|
@ -17,7 +17,7 @@ public interface ParameterBind<T> {
|
||||||
*
|
*
|
||||||
* @return The bound value.
|
* @return The bound value.
|
||||||
*/
|
*/
|
||||||
public T getValue();
|
T getValue();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* If {@code <T>} represents a DATE/TIME type value, JPA usually allows specifying the particular parts of
|
* If {@code <T>} represents a DATE/TIME type value, JPA usually allows specifying the particular parts of
|
||||||
|
@ -25,5 +25,5 @@ public interface ParameterBind<T> {
|
||||||
*
|
*
|
||||||
* @return The explicitly supplied TemporalType.
|
* @return The explicitly supplied TemporalType.
|
||||||
*/
|
*/
|
||||||
public TemporalType getExplicitTemporalType();
|
TemporalType getExplicitTemporalType();
|
||||||
}
|
}
|
||||||
|
|
|
@ -35,6 +35,16 @@ public interface ParameterRegistrationImplementor<T> extends ParameterRegistrati
|
||||||
*/
|
*/
|
||||||
Type getHibernateType();
|
Type getHibernateType();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If no value is bound for this parameter registration, is the passing of NULL
|
||||||
|
* to the JDBC CallableStatement for that parameter enabled? This effectively controls
|
||||||
|
* whether default values for the argument as defined in the database are applied or not.
|
||||||
|
*
|
||||||
|
* @return {@code true} indicates that NULL will be passed to the JDBC driver, effectively disabling
|
||||||
|
* the application of the default argument value defined in the database; {@code false} indicates
|
||||||
|
* that the parameter will simply be ignored, with the assumption that the corresponding argument
|
||||||
|
* defined a default value.
|
||||||
|
*/
|
||||||
boolean isPassNullsEnabled();
|
boolean isPassNullsEnabled();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -28,12 +28,13 @@ import org.hibernate.LockMode;
|
||||||
import org.hibernate.jpa.spi.BaseQueryImpl;
|
import org.hibernate.jpa.spi.BaseQueryImpl;
|
||||||
import org.hibernate.jpa.spi.HibernateEntityManagerImplementor;
|
import org.hibernate.jpa.spi.HibernateEntityManagerImplementor;
|
||||||
import org.hibernate.jpa.spi.ParameterBind;
|
import org.hibernate.jpa.spi.ParameterBind;
|
||||||
import org.hibernate.jpa.spi.ParameterRegistration;
|
import org.hibernate.jpa.spi.StoredProcedureQueryParameterRegistration;
|
||||||
import org.hibernate.procedure.NoSuchParameterException;
|
import org.hibernate.procedure.NoSuchParameterException;
|
||||||
import org.hibernate.procedure.ParameterStrategyException;
|
import org.hibernate.procedure.ParameterStrategyException;
|
||||||
import org.hibernate.procedure.ProcedureCall;
|
import org.hibernate.procedure.ProcedureCall;
|
||||||
import org.hibernate.procedure.ProcedureCallMemento;
|
import org.hibernate.procedure.ProcedureCallMemento;
|
||||||
import org.hibernate.procedure.ProcedureOutputs;
|
import org.hibernate.procedure.ProcedureOutputs;
|
||||||
|
import org.hibernate.procedure.spi.ParameterRegistrationImplementor;
|
||||||
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;
|
||||||
|
@ -62,7 +63,12 @@ public class StoredProcedureQueryImpl extends BaseQueryImpl implements StoredPro
|
||||||
super( entityManager );
|
super( entityManager );
|
||||||
this.procedureCall = memento.makeProcedureCall( entityManager.getSession() );
|
this.procedureCall = memento.makeProcedureCall( entityManager.getSession() );
|
||||||
for ( org.hibernate.procedure.ParameterRegistration nativeParamReg : procedureCall.getRegisteredParameters() ) {
|
for ( org.hibernate.procedure.ParameterRegistration nativeParamReg : procedureCall.getRegisteredParameters() ) {
|
||||||
registerParameter( new ParameterRegistrationImpl( this, nativeParamReg ) );
|
registerParameter(
|
||||||
|
new ParameterRegistrationImpl(
|
||||||
|
this,
|
||||||
|
(ParameterRegistrationImplementor) nativeParamReg
|
||||||
|
)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -111,7 +117,7 @@ public class StoredProcedureQueryImpl extends BaseQueryImpl implements StoredPro
|
||||||
registerParameter(
|
registerParameter(
|
||||||
new ParameterRegistrationImpl(
|
new ParameterRegistrationImpl(
|
||||||
this,
|
this,
|
||||||
procedureCall.registerParameter( position, type, mode )
|
(ParameterRegistrationImplementor) procedureCall.registerParameter( position, type, mode )
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -135,7 +141,7 @@ public class StoredProcedureQueryImpl extends BaseQueryImpl implements StoredPro
|
||||||
registerParameter(
|
registerParameter(
|
||||||
new ParameterRegistrationImpl(
|
new ParameterRegistrationImpl(
|
||||||
this,
|
this,
|
||||||
procedureCall.registerParameter( parameterName, type, mode )
|
(ParameterRegistrationImplementor) procedureCall.registerParameter( parameterName, type, mode )
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -453,15 +459,15 @@ public class StoredProcedureQueryImpl extends BaseQueryImpl implements StoredPro
|
||||||
return procedureCall;
|
return procedureCall;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static class ParameterRegistrationImpl<T> implements ParameterRegistration<T> {
|
private static class ParameterRegistrationImpl<T> implements StoredProcedureQueryParameterRegistration<T> {
|
||||||
private final StoredProcedureQueryImpl query;
|
private final StoredProcedureQueryImpl query;
|
||||||
private final org.hibernate.procedure.ParameterRegistration<T> nativeParamRegistration;
|
private final ParameterRegistrationImplementor<T> nativeParamRegistration;
|
||||||
|
|
||||||
private ParameterBind<T> bind;
|
private ParameterBind<T> bind;
|
||||||
|
|
||||||
public ParameterRegistrationImpl(
|
public ParameterRegistrationImpl(
|
||||||
StoredProcedureQueryImpl query,
|
StoredProcedureQueryImpl query,
|
||||||
org.hibernate.procedure.ParameterRegistration<T> nativeParamRegistration) {
|
ParameterRegistrationImplementor<T> nativeParamRegistration) {
|
||||||
this.query = query;
|
this.query = query;
|
||||||
this.nativeParamRegistration = nativeParamRegistration;
|
this.nativeParamRegistration = nativeParamRegistration;
|
||||||
}
|
}
|
||||||
|
@ -496,6 +502,16 @@ public class StoredProcedureQueryImpl extends BaseQueryImpl implements StoredPro
|
||||||
return nativeParamRegistration.getMode();
|
return nativeParamRegistration.getMode();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isPassNullsEnabled() {
|
||||||
|
return nativeParamRegistration.isPassNullsEnabled();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void enablePassingNulls(boolean enabled) {
|
||||||
|
nativeParamRegistration.enablePassingNulls( enabled );
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isBindable() {
|
public boolean isBindable() {
|
||||||
return getMode() == ParameterMode.IN || getMode() == ParameterMode.INOUT;
|
return getMode() == ParameterMode.IN || getMode() == ParameterMode.INOUT;
|
||||||
|
@ -510,7 +526,7 @@ public class StoredProcedureQueryImpl extends BaseQueryImpl implements StoredPro
|
||||||
public void bindValue(T value, TemporalType specifiedTemporalType) {
|
public void bindValue(T value, TemporalType specifiedTemporalType) {
|
||||||
validateBinding( getParameterType(), value, specifiedTemporalType );
|
validateBinding( getParameterType(), value, specifiedTemporalType );
|
||||||
|
|
||||||
nativeParamRegistration.bindValue( value,specifiedTemporalType );
|
nativeParamRegistration.bindValue( value, specifiedTemporalType );
|
||||||
|
|
||||||
if ( bind == null ) {
|
if ( bind == null ) {
|
||||||
bind = new ParameterBind<T>() {
|
bind = new ParameterBind<T>() {
|
||||||
|
|
|
@ -31,14 +31,14 @@ public interface ParameterRegistration<T> extends Parameter<T> {
|
||||||
* we have either a named parameter ({@link #getName()} would return a non-{@code null} value) or a native
|
* we have either a named parameter ({@link #getName()} would return a non-{@code null} value) or a native
|
||||||
* Hibernate positional parameter.
|
* Hibernate positional parameter.
|
||||||
*/
|
*/
|
||||||
public boolean isJpaPositionalParameter();
|
boolean isJpaPositionalParameter();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Access to the query that this parameter belongs to.
|
* Access to the query that this parameter belongs to.
|
||||||
*
|
*
|
||||||
* @return The defining query
|
* @return The defining query
|
||||||
*/
|
*/
|
||||||
public Query getQuery();
|
Query getQuery();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieves the parameter "mode" which describes how the parameter is defined in the actual database procedure
|
* Retrieves the parameter "mode" which describes how the parameter is defined in the actual database procedure
|
||||||
|
@ -46,7 +46,7 @@ public interface ParameterRegistration<T> extends Parameter<T> {
|
||||||
*
|
*
|
||||||
* @return The parameter mode.
|
* @return The parameter mode.
|
||||||
*/
|
*/
|
||||||
public ParameterMode getMode();
|
ParameterMode getMode();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Can we bind (set) values on this parameter? Generally this is {@code true}, but would not be in the case
|
* Can we bind (set) values on this parameter? Generally this is {@code true}, but would not be in the case
|
||||||
|
@ -54,14 +54,14 @@ public interface ParameterRegistration<T> extends Parameter<T> {
|
||||||
*
|
*
|
||||||
* @return Whether the parameter is bindable (can set be called).
|
* @return Whether the parameter is bindable (can set be called).
|
||||||
*/
|
*/
|
||||||
public boolean isBindable();
|
boolean isBindable();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* If bindable, bind the value.
|
* If bindable, bind the value.
|
||||||
*
|
*
|
||||||
* @param value The value to bind.
|
* @param value The value to bind.
|
||||||
*/
|
*/
|
||||||
public void bindValue(T value);
|
void bindValue(T value);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* If bindable, bind the value using the specific temporal type.
|
* If bindable, bind the value using the specific temporal type.
|
||||||
|
@ -69,12 +69,12 @@ public interface ParameterRegistration<T> extends Parameter<T> {
|
||||||
* @param value The value to bind
|
* @param value The value to bind
|
||||||
* @param specifiedTemporalType The temporal type to use in binding
|
* @param specifiedTemporalType The temporal type to use in binding
|
||||||
*/
|
*/
|
||||||
public void bindValue(T value, TemporalType specifiedTemporalType);
|
void bindValue(T value, TemporalType specifiedTemporalType);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* If bindable, get the current binding.
|
* If bindable, get the current binding.
|
||||||
*
|
*
|
||||||
* @return The current binding
|
* @return The current binding
|
||||||
*/
|
*/
|
||||||
public ParameterBind<T> getBind();
|
ParameterBind<T> getBind();
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,38 @@
|
||||||
|
/*
|
||||||
|
* 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.spi;
|
||||||
|
|
||||||
|
import org.hibernate.procedure.spi.ParameterRegistrationImplementor;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ParameterRegistration extension specifically for stored procedure parameters
|
||||||
|
* exposing some functionality of Hibernate's native
|
||||||
|
* {@link org.hibernate.procedure.ParameterRegistration} contract
|
||||||
|
*
|
||||||
|
* @author Steve Ebersole
|
||||||
|
*/
|
||||||
|
public interface StoredProcedureQueryParameterRegistration<T> extends ParameterRegistration<T> {
|
||||||
|
/**
|
||||||
|
* How will an unbound value be handled in terms of the JDBC parameter?
|
||||||
|
*
|
||||||
|
* @return {@code true} here indicates that NULL should be passed; {@code false} indicates
|
||||||
|
* that it is ignored.
|
||||||
|
*
|
||||||
|
* @see ParameterRegistrationImplementor#isPassNullsEnabled()
|
||||||
|
*/
|
||||||
|
boolean isPassNullsEnabled();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Controls how unbound values for this IN/INOUT parameter registration will be handled prior to
|
||||||
|
* execution. For details see {@link org.hibernate.procedure.ParameterRegistration#enablePassingNulls}
|
||||||
|
*
|
||||||
|
* @param enabled {@code true} indicates that the NULL should be passed; {@code false} indicates it should not.
|
||||||
|
*
|
||||||
|
* @see org.hibernate.procedure.ParameterRegistration#enablePassingNulls
|
||||||
|
*/
|
||||||
|
void enablePassingNulls(boolean enabled);
|
||||||
|
}
|
Loading…
Reference in New Issue