{"record":{"id":"f7f4ffe754f124f2","repo":"hibernate/hibernate-orm","slug":"unsupported-enum-type-passed-to-ordinal-functi","errorCode":null,"errorMessage":"Unsupported enum type passed to 'ordinal()' function: %s","messagePattern":"Unsupported enum type passed to 'ordinal\\(\\)' function: (.+?)","errorType":"exception","errorClass":"QueryException","httpStatus":null,"severity":"error","filePath":"hibernate-core/src/main/java/org/hibernate/dialect/function/OrdinalFunction.java","lineNumber":82,"sourceCode":"\t\telse if ( argumentType.isString() || argumentType.getDefaultSqlTypeCode() == SqlTypes.ENUM ) {\n\n\t\t\tEnumJavaType<?> enumJavaType = (EnumJavaType<?>) singleJdbcMapping.getMappedJavaType();\n\t\t\tObject[] enumConstants = enumJavaType.getJavaTypeClass().getEnumConstants();\n\n\t\t\tsqlAppender.appendSql( \"case \" );\n\t\t\tsingleExpression.accept( walker );\n\t\t\tfor ( Object e : enumConstants ) {\n\t\t\t\tEnum<?> enumValue = (Enum<?>) e;\n\t\t\t\tsqlAppender.appendSql( \" when \" );\n\t\t\t\tsqlAppender.appendSingleQuoteEscapedString( (String) singleJdbcMapping.convertToRelationalValue(\n\t\t\t\t\t\tenumValue.toString() ) );\n\t\t\t\tsqlAppender.appendSql( \" then \" );\n\t\t\t\tsqlAppender.appendSql( enumValue.ordinal() );\n\t\t\t}\n\t\t\tsqlAppender.appendSql( \" end\" );\n\t\t}\n\t\telse {\n\t\t\tthrow new QueryException( \"Unsupported enum type passed to 'ordinal()' function: \" + argumentType );\n\t\t}\n\t}\n\n\t@Override\n\tpublic String getArgumentListSignature() {\n\t\treturn \"(ENUM arg)\";\n\t}\n}\n","sourceCodeStart":64,"sourceCodeEnd":91,"githubUrl":"https://github.com/hibernate/hibernate-orm/blob/fad1729dce015f908198d57a8d80274a30f905a5/hibernate-core/src/main/java/org/hibernate/dialect/function/OrdinalFunction.java#L64-L91","documentation":"The HQL ordinal() function converts a name-mapped enum to its ordinal by rendering a CASE expression over the enum constants' names, converting each name with the attribute's single JDBC mapping. This is only implementable when the mapping can turn an enum name into its relational (string) value; any other argument type — ORDINAL-mapped enum (the JPA default), an enum behind an AttributeConverter, or a non-enum expression — throws QueryException at render time.","triggerScenarios":"HQL: select ordinal(e.status) from MyEntity e where status is @Enumerated(ORDINAL) (or has no @Enumerated at all), uses a converter/custom JdbcType, or the argument is not an enum attribute.","commonSituations":"Calling ordinal() on enums left at the JPA default mapping; entities retrofitted with AttributeConverters; assuming ordinal() is a generic enum-to-int function for every mapping style.","solutions":["Annotate the attribute @Enumerated(EnumType.STRING) so the CASE rendering works","If the enum is already ORDINAL-mapped, drop ordinal() — the column already holds the ordinal value","Remove the AttributeConverter/custom JdbcType from that attribute or make it name-based","Upgrade Hibernate for widened ordinal() support across mappings"],"exampleFix":"// before\n@Enumerated          // defaults to ORDINAL -> ordinal(e.status) throws\nprivate Status status;\n\n// after\n@Enumerated(EnumType.STRING)\nprivate Status status;","handlingStrategy":"type-guard","validationCode":"// Before exposing ordinal() in HQL templates, verify the attribute is STRING-mapped\nstatic boolean isStringMappedEnum(Class<?> entity, String field) throws Exception {\n    Enumerated e = entity.getDeclaredField(field).getAnnotation(Enumerated.class);\n    return e != null && e.value() == EnumType.STRING;\n}","typeGuard":"static boolean supportsOrdinalHql(Class<?> entity, String field) throws Exception {\n    Class<?> type = entity.getDeclaredField(field).getType();\n    if (!type.isEnum()) return false;\n    Enumerated e = entity.getDeclaredField(field).getAnnotation(Enumerated.class);\n    return e != null && e.value() == EnumType.STRING;\n}","tryCatchPattern":"try {\n    return em.createQuery(\"select ordinal(e.status) from E e\", Integer.class).getResultList();\n} catch (org.hibernate.QueryException e) {\n    if (e.getMessage() != null && e.getMessage().contains(\"ordinal()\")) {\n        throw new QuerySetupException(\"ordinal() requires a STRING-mapped enum attribute\", e);\n    }\n    throw e;\n}","preventionTips":["Declare @Enumerated(EnumType.STRING) explicitly on every enum attribute","Drop ordinal() for ORDINAL-mapped enums — the value is already numeric","Audit AttributeConverters on enums before using enum functions in HQL"],"tags":["hibernate","hql","enum","ordinal","entity-mapping"],"backgroundTag":"enum-mapping-unsupported","analyzedSha":"fad1729dce015f908198d57a8d80274a30f905a5","analyzedAt":"2026-08-22T04:13:57.527Z","schemaVersion":2},"datasetVersion":"2026-08-22T09:17:25.309Z"}