When a *_Custom type_* (extended from_ org from_org .hibernate.usertype.UserType_) is registered as an expected parameter from entityManager.createStoredProcedureQuery the validateBinding method expects an instance object of the same type, when probably the expected one should be *_UserType.returnedClass_*:
BaseQueryImpl:957 {code:java} private static boolean isValidBindValue(Class expectedType, Object value, TemporalType temporalType) { if ( expectedType.isInstance( value ) ) { return true; }
if ( temporalType != null ) { final boolean parameterDeclarationIsTemporal = Date.class.isAssignableFrom( expectedType ) || Calendar.class.isAssignableFrom( expectedType ); final boolean bindIsTemporal = Date.class.isInstance( value ) || Calendar.class.isInstance( value );
if ( parameterDeclarationIsTemporal && bindIsTemporal ) { return true; } }
return false; } {code}
It implies that the procedure call should be made with an instance of the UserTypeDefinition and hold the real parameter inside:
{code:java} StoredProcedureQuery q = entityManager.createStoredProcedureQuery(GETXML_PROCEDURE) .registerStoredProcedureParameter("QUERY_STATEMENT", String.class, ParameterMode.IN) .registerStoredProcedureParameter("QUERY_PARAMS", BindParametersListUserType.class, ParameterMode.IN) .registerStoredProcedureParameter("RESULT_CLOB", Class.class, ParameterMode.OUT) .setParameter("QUERY_STATEMENT", queryString) .setParameter("QUERY_PARAMS", new BindParametersListUserType(bindParameters)); q.execute(); {code}
and provide a workaround in implemented UserType methods to receive the UserType Object instead of the expected declared returnedClass:
{code:java} @Override public void nullSafeSet(PreparedStatement st, Object value, int index, SessionImplementor session) throws HibernateException, SQLException { if (value == null) { st.setNull(index, DB_OBJECT_LIST_TYPE, DB_OBJECT_TYPE_NAME); } else { final Connection connection = st.getConnection(); final OracleConnection oraConnection = connection.unwrap(OracleConnection.class); {color:#f6c342}{color:#d04437}final BindParametersList bindParametersList = (BindParametersList) ((BindParametersListUserType) value).getExpectedParamObject();{color}{color} List<Object> elements = new ArrayList<Object>(); for(BindParameter bindParameter : bindParametersList.getBindParameters()){ Object[] attributes = new Object[] { bindParameter.getName(), bindParameter.getType(), bindParameter.getNumber(), bindParameter.getString(), convertDate(bindParameter.getDate()) }; Struct struct = oraConnection.createStruct(DB_OBJECT_TYPE_NAME, attributes); elements.add(struct); } Array array = oraConnection.createARRAY(DB_OBJECT_LIST_TYPE_NAME, elements.toArray()); st.setObject(index, array, DB_OBJECT_LIST_TYPE); } } {code}
|
|