{"record":{"id":"b272fe570ada1fcc","repo":"hibernate/hibernate-orm","slug":"error-attempting-to-apply-attributeconverter-b272fe","errorCode":null,"errorMessage":"Error attempting to apply AttributeConverter","messagePattern":"Error attempting to apply AttributeConverter","errorType":"exception","errorClass":"PersistenceException","httpStatus":null,"severity":"error","filePath":"hibernate-core/src/main/java/org/hibernate/type/descriptor/converter/internal/AttributeConverterInstance.java","lineNumber":47,"sourceCode":"\tpublic AttributeConverterInstance(\n\t\t\tAttributeConverter<O, R> converter,\n\t\t\tJavaType<O> domainJavaType,\n\t\t\tJavaType<R> jdbcJavaType) {\n\t\tthis.converter = converter;\n\t\tthis.domainJavaType = domainJavaType;\n\t\tthis.jdbcJavaType = jdbcJavaType;\n\t}\n\n\t@Override\n\tpublic O toDomainValue(R relationalForm) {\n\t\ttry {\n\t\t\treturn converter.convertToEntityAttribute( relationalForm );\n\t\t}\n\t\tcatch (PersistenceException pe) {\n\t\t\tthrow pe;\n\t\t}\n\t\tcatch (RuntimeException re) {\n\t\t\tthrow new PersistenceException( \"Error attempting to apply AttributeConverter\", re );\n\t\t}\n\t}\n\n\t@Override\n\tpublic R toRelationalValue(O domainForm) {\n\t\ttry {\n\t\t\treturn converter.convertToDatabaseColumn( domainForm );\n\t\t}\n\t\tcatch (PersistenceException pe) {\n\t\t\tthrow pe;\n\t\t}\n\t\tcatch (RuntimeException re) {\n\t\t\tthrow new PersistenceException( \"Error attempting to apply AttributeConverter: \" + re.getMessage(), re );\n\t\t}\n\t}\n\n\t@Override\n\tpublic JavaType<O> getDomainJavaType() {","sourceCodeStart":29,"sourceCodeEnd":65,"githubUrl":"https://github.com/hibernate/hibernate-orm/blob/fad1729dce015f908198d57a8d80274a30f905a5/hibernate-core/src/main/java/org/hibernate/type/descriptor/converter/internal/AttributeConverterInstance.java#L29-L65","documentation":"Same read-path wrapping as its AttributeConverterBean counterpart, but thrown from AttributeConverterInstance - the wrapper Hibernate uses when it instantiates the converter itself (no bean manager). Any non-PersistenceException RuntimeException escaping convertToEntityAttribute during entity load becomes this PersistenceException with the original failure as cause.","triggerScenarios":"Loading/querying an entity with a @Convert attribute (or autoApply converter) where Hibernate directly instantiated the converter, and convertToEntityAttribute throws on the stored value - null column, unparsable string, unrecognized enum code.","commonSituations":"Dirty legacy data; column type change after a dialect or driver upgrade; converters that assume non-null input; native query results fed through a converter with values in an unexpected format.","solutions":["Check the cause (getCause()) for the real converter exception","Harden convertToEntityAttribute against null and unknown values","Fix or migrate the stored data / column type so the relational form matches the converter's declared database-column type","Reproduce with a direct unit test of the converter using the exact failing DB value"],"exampleFix":"// before\n@Override\npublic MonetaryAmount convertToEntityAttribute(Long cents) {\n    return MonetaryAmount.ofCents(cents); // NPE when column is NULL\n}\n// after\n@Override\npublic MonetaryAmount convertToEntityAttribute(Long cents) {\n    return cents == null ? null : MonetaryAmount.ofCents(cents);\n}","handlingStrategy":"try-catch","validationCode":"// pre-flight the distinct stored values through the converter before deploying\nfor (String v : rawColumnValues) {\n    if (v != null && converter.convertToEntityAttribute(v) == null && !allowsNull) {\n        throw new IllegalStateException(\"Row value not convertible: \" + v);\n    }\n}","typeGuard":"// expose a non-throwing probe next to the converter\npublic static boolean canConvert(String dbValue) {\n    if (dbValue == null) return true;\n    try { convertToEntityAttributeImpl(dbValue); return true; }\n    catch (RuntimeException e) { return false; }\n}","tryCatchPattern":"try {\n    return session.createQuery(\"from Order o where o.customer.id = :cid\", Order.class)\n                  .setParameter(\"cid\", cid).list();\n} catch (PersistenceException e) {\n    if (e.getMessage() != null && e.getMessage().contains(\"apply AttributeConverter\")) {\n        // inspect e.getCause(): dirty data or type mismatch on a converted column\n        throw new DataQualityException(\"Converted column holds bad data\", e.getCause());\n    }\n    throw e;\n}","preventionTips":["Treat converters as an anti-corruption layer: expect and handle unknown stored values","Pin column types in migrations so the driver always delivers the declared relational type","Add canParse probes to data-migration smoke tests","Log the raw relational form in converter error paths"],"tags":["hibernate","orm","jpa","attribute-converter","persistence-exception","entity-loading"],"backgroundTag":"jpa-attribute-converter-failed","analyzedSha":"fad1729dce015f908198d57a8d80274a30f905a5","analyzedAt":"2026-08-22T04:13:57.527Z","schemaVersion":2},"datasetVersion":"2026-08-22T09:17:25.309Z"}