Search in sources :

Example 1 with ProcedureParameterExtractionAware

use of org.hibernate.type.ProcedureParameterExtractionAware in project hibernate-orm by hibernate.

the class AbstractParameterRegistrationImpl method prepare.

@Override
public void prepare(CallableStatement statement, int startIndex) throws SQLException {
    // initially set up the Type we will use for binding as the explicit type.
    Type typeToUse = hibernateType;
    int[] sqlTypesToUse = sqlTypes;
    // however, for Calendar binding with an explicit TemporalType we may need to adjust this...
    if (bind != null && bind.getExplicitTemporalType() != null) {
        if (Calendar.class.isInstance(bind.getValue())) {
            switch(bind.getExplicitTemporalType()) {
                case TIMESTAMP:
                    {
                        typeToUse = CalendarType.INSTANCE;
                        sqlTypesToUse = typeToUse.sqlTypes(session().getFactory());
                        break;
                    }
                case DATE:
                    {
                        typeToUse = CalendarDateType.INSTANCE;
                        sqlTypesToUse = typeToUse.sqlTypes(session().getFactory());
                        break;
                    }
                case TIME:
                    {
                        typeToUse = CalendarTimeType.INSTANCE;
                        sqlTypesToUse = typeToUse.sqlTypes(session().getFactory());
                        break;
                    }
            }
        }
    }
    this.startIndex = startIndex;
    if (mode == ParameterMode.IN || mode == ParameterMode.INOUT || mode == ParameterMode.OUT) {
        if (mode == ParameterMode.INOUT || mode == ParameterMode.OUT) {
            if (sqlTypesToUse.length > 1) {
                // there is more than one column involved; see if the Hibernate Type can handle
                // multi-param extraction...
                final boolean canHandleMultiParamExtraction = ProcedureParameterExtractionAware.class.isInstance(hibernateType) && ((ProcedureParameterExtractionAware) hibernateType).canDoExtraction();
                if (!canHandleMultiParamExtraction) {
                    // it cannot...
                    throw new UnsupportedOperationException("Type [" + hibernateType + "] does support multi-parameter value extraction");
                }
            }
            // e.g., Oracle.
            if (sqlTypesToUse.length == 1 && procedureCall.getParameterStrategy() == ParameterStrategy.NAMED && canDoNameParameterBinding()) {
                statement.registerOutParameter(getName(), sqlTypesToUse[0]);
            } else {
                for (int i = 0; i < sqlTypesToUse.length; i++) {
                    statement.registerOutParameter(startIndex + i, sqlTypesToUse[i]);
                }
            }
        }
        if (mode == ParameterMode.INOUT || mode == ParameterMode.IN) {
            if (bind == null || bind.getValue() == null) {
                // parameter defines a default value.  Deferring to that information would be the best option
                if (passNulls) {
                    log.debugf("Stored procedure [%s] IN/INOUT parameter [%s] not bound and `passNulls` was set to true; binding NULL", procedureCall.getProcedureName(), this);
                    if (this.procedureCall.getParameterStrategy() == ParameterStrategy.NAMED && canDoNameParameterBinding()) {
                        ((ProcedureParameterNamedBinder) typeToUse).nullSafeSet(statement, null, this.getName(), session());
                    } else {
                        typeToUse.nullSafeSet(statement, null, startIndex, session());
                    }
                } else {
                    log.debugf("Stored procedure [%s] IN/INOUT parameter [%s] not bound and `passNulls` was set to false; assuming procedure defines default value", procedureCall.getProcedureName(), this);
                }
            } else {
                if (this.procedureCall.getParameterStrategy() == ParameterStrategy.NAMED && canDoNameParameterBinding()) {
                    ((ProcedureParameterNamedBinder) typeToUse).nullSafeSet(statement, bind.getValue(), this.getName(), session());
                } else {
                    typeToUse.nullSafeSet(statement, bind.getValue(), startIndex, session());
                }
            }
        }
    } else {
        // we have a REF_CURSOR type param
        if (procedureCall.getParameterStrategy() == ParameterStrategy.NAMED) {
            session().getFactory().getServiceRegistry().getService(RefCursorSupport.class).registerRefCursorParameter(statement, getName());
        } else {
            session().getFactory().getServiceRegistry().getService(RefCursorSupport.class).registerRefCursorParameter(statement, startIndex);
        }
    }
}
Also used : RefCursorSupport(org.hibernate.engine.jdbc.cursor.spi.RefCursorSupport) TemporalType(javax.persistence.TemporalType) CalendarTimeType(org.hibernate.type.CalendarTimeType) CalendarType(org.hibernate.type.CalendarType) CalendarDateType(org.hibernate.type.CalendarDateType) Type(org.hibernate.type.Type) ProcedureParameterNamedBinder(org.hibernate.type.ProcedureParameterNamedBinder) ProcedureParameterExtractionAware(org.hibernate.type.ProcedureParameterExtractionAware)

Aggregations

TemporalType (javax.persistence.TemporalType)1 RefCursorSupport (org.hibernate.engine.jdbc.cursor.spi.RefCursorSupport)1 CalendarDateType (org.hibernate.type.CalendarDateType)1 CalendarTimeType (org.hibernate.type.CalendarTimeType)1 CalendarType (org.hibernate.type.CalendarType)1 ProcedureParameterExtractionAware (org.hibernate.type.ProcedureParameterExtractionAware)1 ProcedureParameterNamedBinder (org.hibernate.type.ProcedureParameterNamedBinder)1 Type (org.hibernate.type.Type)1