{"record":{"id":"024ce12188c366c1","repo":"hibernate/hibernate-orm","slug":"property-property-is-annotated-orderby-but","errorCode":null,"errorMessage":"Property '${property}' is annotated '@OrderBy' but is not of type 'Collection' or 'Map'","messagePattern":"Property '(.+?)' is annotated '@OrderBy' but is not of type 'Collection' or 'Map'","errorType":"exception","errorClass":"AnnotationException","httpStatus":null,"severity":"error","filePath":"hibernate-core/src/main/java/org/hibernate/boot/model/internal/PropertyBinder.java","lineNumber":653,"sourceCode":"\t\t\t\t\tfinal String options =\n\t\t\t\t\t\t\tisBlank( existing )\n\t\t\t\t\t\t\t\t\t? exclusion\n\t\t\t\t\t\t\t\t\t: existing + \" \" + exclusion;\n\t\t\t\t\tcolumn.setOptions( options );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate void validateAnnotationsAgainstType() {\n\t\tif ( memberDetails != null ) {\n\t\t\tfinal var type = memberDetails.getType();\n\t\t\tif ( !(type instanceof ArrayTypeDetails) ) {\n\t\t\t\tcheckAnnotation( OrderColumn.class, List.class );\n\t\t\t\tif ( memberDetails.hasDirectAnnotationUsage( OrderBy.class )\n\t\t\t\t\t\t&& !type.isImplementor( Collection.class )\n\t\t\t\t\t\t&& !type.isImplementor( Map.class ) ) {\n\t\t\t\t\tthrow new AnnotationException( \"Property '\" + qualify( holder.getPath(), name )\n\t\t\t\t\t\t\t+ \"' is annotated '@OrderBy' but is not of type 'Collection' or 'Map'\" );\n\t\t\t\t}\n\t\t\t}\n\t\t\tcheckAnnotation( MapKey.class, Map.class );\n\t\t\tcheckAnnotation( MapKeyColumn.class, Map.class );\n\t\t\tcheckAnnotation( MapKeyClass.class, Map.class );\n\t\t\tcheckAnnotation( MapKeyEnumerated.class, Map.class );\n\t\t\tcheckAnnotation( MapKeyTemporal.class, Map.class );\n\t\t\tcheckAnnotation( MapKeyColumn.class, Map.class );\n\t\t\tcheckAnnotation( MapKeyJoinColumn.class, Map.class );\n\t\t\tcheckAnnotation( MapKeyJoinColumns.class, Map.class );\n\t\t}\n\t}\n\n\tprivate void checkAnnotation(Class<? extends Annotation> annotationClass, Class<?> propertyType) {\n\t\tif ( memberDetails.hasDirectAnnotationUsage( annotationClass )\n\t\t\t\t&& !memberDetails.getType().isImplementor( propertyType ) ) {\n\t\t\tthrow new AnnotationException( \"Property '\" + qualify( holder.getPath(), name )","sourceCodeStart":635,"sourceCodeEnd":671,"githubUrl":"https://github.com/hibernate/hibernate-orm/blob/fad1729dce015f908198d57a8d80274a30f905a5/hibernate-core/src/main/java/org/hibernate/boot/model/internal/PropertyBinder.java#L635-L671","documentation":"@OrderBy specifies in-memory ordering of a collection or map at load time, so JPA only allows it on attributes whose type implements Collection or Map. PropertyBinder validates this during metadata building and throws AnnotationException when the annotated property is a basic type, embedded, or single-valued association.","triggerScenarios":"@OrderBy(\"email\") on a scalar field like private String email; @OrderBy on a single @OneToOne/@ManyToOne association; @OrderBy on an embeddable attribute; code migrated from a collection to a single value (e.g. List<Line> collapsed to Line) with the annotation left behind.","commonSituations":"Changing a field's type during refactoring (collection to single object) without cleaning annotations; copy-paste of collection annotations onto new scalar fields; generated code from templates targeting collections.","solutions":["Remove @OrderBy — the property is not orderable.","If ordering was intended, the property should be a List/Set/Collection (or Map) of elements.","For ordering single results there is nothing to order: rely on query-level ORDER BY in JPQL/Criteria instead."],"exampleFix":"// before\n@OrderBy(\"createdAt\")\nprivate Comment comment;   // single-valued => rejected\n\n// after (choose one)\n// 1) it should be a collection:\n@OrderBy(\"createdAt\")\nprivate List<Comment> comments = new ArrayList<>();\n// 2) it really is single-valued: delete the @OrderBy and sort in queries","handlingStrategy":"validation","validationCode":"// Guard @OrderBy against non-collection/non-map properties before boot\nfor (Class<?> entity : annotatedClasses) {\n    for (Field f : entity.getDeclaredFields()) {\n        if (f.isAnnotationPresent(OrderBy.class)\n                && !(Collection.class.isAssignableFrom(f.getType()) || Map.class.isAssignableFrom(f.getType()))) {\n            throw new IllegalStateException(\"@OrderBy on non-collection field \" + f);\n        }\n    }\n}","typeGuard":"static boolean supportsOrderBy(Class<?> propertyType) {\n    return Collection.class.isAssignableFrom(propertyType) || Map.class.isAssignableFrom(propertyType);\n}","tryCatchPattern":"try {\n    SessionFactory sf = cfg.buildSessionFactory();\n} catch (AnnotationException e) {\n    throw new IllegalStateException(\"Collection annotation misuse: \" + e.getMessage(), e);\n}","preventionTips":["When changing a field from collection to single-valued (or back), sweep the field for collection-only annotations","Keep a lint/review checklist: @OrderBy => Collection/Map"],"tags":["hibernate","jpa","order-by","annotation-misuse","collection","bootstrap"],"backgroundTag":"jpa-annotation-type-mismatch","analyzedSha":"fad1729dce015f908198d57a8d80274a30f905a5","analyzedAt":"2026-08-22T04:13:57.527Z","schemaVersion":2},"datasetVersion":"2026-08-22T09:17:25.309Z"}