{"record":{"id":"5d21490fc3873d4d","repo":"hibernate/hibernate-orm","slug":"expecting-raw-jdbc-value-of-type-s-but-found","errorCode":null,"errorMessage":"Expecting raw JDBC value of type `%s`, but found `%s` : [%s]","messagePattern":"Expecting raw JDBC value of type `(.+?)`, but found `(.+?)` : \\[(.+?)\\]","errorType":"exception","errorClass":"HibernateException","httpStatus":null,"severity":"error","filePath":"hibernate-core/src/main/java/org/hibernate/sql/results/graph/basic/BasicResultAssembler.java","lineNumber":63,"sourceCode":"\t/**\n\t * Access to the raw value (unconverted, if a converter applied)\n\t */\n\tpublic Object extractRawValue(RowProcessingState rowProcessingState) {\n\t\tif ( unwrapRowProcessingState ) {\n\t\t\trowProcessingState = rowProcessingState.unwrap();\n\t\t}\n\t\treturn rowProcessingState.getJdbcValue( valuesArrayPosition );\n\t}\n\n\t@Override\n\tpublic J assemble(RowProcessingState rowProcessingState) {\n\t\tfinal Object jdbcValue = extractRawValue( rowProcessingState );\n\n\t\tif ( valueConverter != null ) {\n\t\t\tif ( jdbcValue != null\n\t\t\t\t\t// the raw value type should be the converter's relational-JTD\n\t\t\t\t\t&& !valueConverter.getRelationalJavaType().isInstance( jdbcValue ) ) {\n\t\t\t\tthrow new HibernateException(\n\t\t\t\t\t\tString.format(\n\t\t\t\t\t\t\t\tLocale.ROOT,\n\t\t\t\t\t\t\t\t\"Expecting raw JDBC value of type `%s`, but found `%s` : [%s]\",\n\t\t\t\t\t\t\t\tvalueConverter.getRelationalJavaType().getTypeName(),\n\t\t\t\t\t\t\t\tjdbcValue.getClass().getName(),\n\t\t\t\t\t\t\t\tjdbcValue\n\t\t\t\t\t\t)\n\t\t\t\t);\n\t\t\t}\n\t\t\t// Safe unchecked cast due to check above\n\t\t\t@SuppressWarnings({\"unchecked\", \"rawtypes\"})\n\t\t\tfinal Object domainValue =\n\t\t\t\t\t( (BasicValueConverter) valueConverter )\n\t\t\t\t\t\t\t.toDomainValue( jdbcValue );\n\t\t\treturn (J) domainValue;\n\t\t}\n\t\telse {\n\t\t\treturn (J) jdbcValue;","sourceCodeStart":45,"sourceCodeEnd":81,"githubUrl":"https://github.com/hibernate/hibernate-orm/blob/fad1729dce015f908198d57a8d80274a30f905a5/hibernate-core/src/main/java/org/hibernate/sql/results/graph/basic/BasicResultAssembler.java#L45-L81","documentation":"BasicResultAssembler applies a valueConverter (AttributeConverter-backed or otherwise) to the raw JDBC value after checking that the raw value is an instance of the converter's relational Java type. If the JDBC driver returns a different runtime type than the converter's relational type declares - String vs UUID, or a driver-specific class - Hibernate throws HibernateException 'Expecting raw JDBC value of type `X`, but found `Y`'.","triggerScenarios":"A converter whose relational type mismatches what the driver returns for the column: AttributeConverter<UUID,String> against a native UUID column (PostgreSQL returns java.util.UUID), converters on TIMESTAMP columns where the driver returns its own timestamp class, custom JdbcType pairings with the wrong relational Java type.","commonSituations":"PostgreSQL/Oracle native column types with converters written for String; switching or upgrading JDBC drivers (ojdbc, mssql-jdbc) changing extracted runtime types; @JdbcTypeCode mismatches after Hibernate upgrades.","solutions":["Align the converter's relational type with what the driver returns - for a native UUID column use AttributeConverter<UUID,UUID> or map the attribute as UUID without a converter","Force extraction to the expected type: annotate with @JdbcTypeCode(SqlTypes.VARCHAR) (or the fitting JdbcType) so raw values arrive as the converter's relational type","Upgrade Hibernate/the dialect - improved JavaType/JdbcType resolution fixed several driver-type mismatches","Verify with a smoke test that reads one row of each converted column right after startup, so mismatches surface at deploy time, not mid-request"],"exampleFix":"// before\n@Converter\npublic class UuidConverter implements AttributeConverter<UUID, String> { ... } // column is native uuid\n\n// after\n// map native uuid columns as UUID directly, no converter\n@JdbcTypeCode( SqlTypes.UUID )\nprivate UUID documentId;","handlingStrategy":"try-catch","validationCode":"// smoke test at startup: read one row of every converter-mapped column\nconverterMappedAttributes.forEach( attr ->\n    session.createQuery( \"select e.\" + attr + \" from Entity e\", Object.class )\n           .setMaxResults( 1 ).getResultList() );","typeGuard":null,"tryCatchPattern":"try {\n    return query.list();\n} catch ( HibernateException e ) {\n    if ( e.getMessage() != null && e.getMessage().startsWith( \"Expecting raw JDBC value of type\" ) ) {\n        // converter relational type mismatched the driver type: fix @JdbcTypeCode / converter\n        throw new IllegalStateException( \"Mapping/driver mismatch on a converted column: \" + e.getMessage(), e );\n    }\n    throw e;\n}","preventionTips":["Match converter relational types to the driver's actual returned type (native UUID columns return java.util.UUID, not String)","Pin extraction with @JdbcTypeCode when the default driver mapping disagrees with the converter","Add a startup smoke test that reads one row of each converted column so mismatches fail at deploy time"],"tags":["hibernate","orm","attribute-converter","jdbc-type","dialect","result-mapping"],"backgroundTag":"jdbc-type-mismatch","analyzedSha":"fad1729dce015f908198d57a8d80274a30f905a5","analyzedAt":"2026-08-22T04:13:57.527Z","schemaVersion":2},"datasetVersion":"2026-08-22T09:17:25.309Z"}