{"record":{"id":"2eaf8068fe3f6873","repo":"hibernate/hibernate-orm","slug":"the-jtds-driver-does-not-support-calling-functions","errorCode":null,"errorMessage":"The jTDS driver does not support calling functions through the JDBC CallableStatement API","messagePattern":"The jTDS driver does not support calling functions through the JDBC CallableStatement API","errorType":"exception","errorClass":"QueryException","httpStatus":null,"severity":"error","filePath":"hibernate-core/src/main/java/org/hibernate/procedure/internal/JTDSCallableStatementSupport.java","lineNumber":48,"sourceCode":"\tpublic JdbcOperationQueryCall interpretCall(ProcedureCallImplementor procedureCall) {\n\t\tfinal String procedureName = procedureCall.getProcedureName();\n\t\tfinal FunctionReturnImplementor<?> functionReturn = procedureCall.getFunctionReturn();\n\t\tfinal ProcedureParameterMetadataImplementor parameterMetadata = procedureCall.getParameterMetadata();\n\t\tfinal List<? extends ProcedureParameterImplementor<?>> registrations = parameterMetadata.getRegistrationsAsList();\n\t\tfinal int paramStringSizeEstimate;\n\t\tif ( functionReturn == null && parameterMetadata.hasNamedParameters() ) {\n\t\t\t// That's just a rough estimate. I guess most params will have fewer than 8 chars on average\n\t\t\tparamStringSizeEstimate = registrations.size() * 12;\n\t\t}\n\t\telse {\n\t\t\t// For every param rendered as '?' we have a comma, hence the estimate\n\t\t\tparamStringSizeEstimate = registrations.size() * 2;\n\t\t}\n\t\tfinal JdbcCallImpl.Builder builder = new JdbcCallImpl.Builder();\n\t\tfinal StringBuilder buffer;\n\t\tfinal int offset;\n\t\tif ( functionReturn != null ) {\n\t\t\tthrow new QueryException( \"The jTDS driver does not support calling functions through the JDBC CallableStatement API\" );\n\t\t}\n\t\toffset = 1;\n\t\tbuffer = new StringBuilder( 9 + procedureName.length() + paramStringSizeEstimate ).append( \"{call \" );\n\n\t\tbuffer.append( procedureName );\n\n\t\tif ( registrations.isEmpty() ) {\n\t\t\tbuffer.append( '(' );\n\t\t}\n\t\telse {\n\t\t\tchar sep = '(';\n\t\t\tfor ( int i = 0; i < registrations.size(); i++ ) {\n\t\t\t\tfinal ProcedureParameterImplementor<?> parameter = registrations.get( i );\n\t\t\t\tif ( parameter.getMode() == ParameterMode.REF_CURSOR ) {\n\t\t\t\t\tthrow new QueryException( \"Dialect [\" + procedureCall.getSession().getJdbcServices().getJdbcEnvironment().getDialect().getClass().getName() + \"] not known to support REF_CURSOR parameters\" );\n\t\t\t\t}\n\t\t\t\tbuffer.append( sep );\n\t\t\t\tfinal JdbcCallParameterRegistration registration = parameter.toJdbcParameterRegistration(","sourceCodeStart":30,"sourceCodeEnd":66,"githubUrl":"https://github.com/hibernate/hibernate-orm/blob/fad1729dce015f908198d57a8d80274a30f905a5/hibernate-core/src/main/java/org/hibernate/procedure/internal/JTDSCallableStatementSupport.java#L30-L66","documentation":"Error \"The jTDS driver does not support calling functions through the JDBC CallableStatement API\" thrown in hibernate/hibernate-orm.","triggerScenarios":"A runtime precondition of the Hibernate API is violated.","commonSituations":"Occurs when application code or configuration does not satisfy the documented contract of the API being called.","solutions":["Switch to a driver that supports CallableStatement function calls, e.g. the Microsoft JDBC driver or jTDS with procedure syntax instead of function syntax.","Call the routine as a stored procedure rather than a function."],"exampleFix":null,"handlingStrategy":null,"validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":[],"tags":[],"backgroundTag":null,"analyzedSha":"fad1729dce015f908198d57a8d80274a30f905a5","analyzedAt":"2026-08-22T04:13:57.527Z","schemaVersion":2},"datasetVersion":"2026-08-22T09:17:25.309Z"}