{"record":{"id":"e536b0794d643ee8","repo":"hibernate/hibernate-orm","slug":"not-null-makes-no-sense-for-in-expression","errorCode":null,"errorMessage":"not null makes no sense for in expression","messagePattern":"not null makes no sense for in expression","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"hibernate-core/src/main/java/org/hibernate/sql/InFragment.java","lineNumber":95,"sourceCode":"\t\t\t\t\tif ( NOT_NULL.equals( value ) ) {\n\t\t\t\t\t\tbuf.append( \" is not null\" );\n\t\t\t\t\t}\n\t\t\t\t\telse {\n\t\t\t\t\t\tbuf.append( '=' ).append( value );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn buf.toString();\n\t\t\t}\n\t\t\tdefault: {\n\t\t\t\tboolean allowNull = false;\n\n\t\t\t\tfor ( Object value : values ) {\n\t\t\t\t\tif ( NULL.equals( value ) ) {\n\t\t\t\t\t\tallowNull = true;\n\t\t\t\t\t}\n\t\t\t\t\telse {\n\t\t\t\t\t\tif ( NOT_NULL.equals( value ) ) {\n\t\t\t\t\t\t\tthrow new IllegalArgumentException( \"not null makes no sense for in expression\" );\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif ( allowNull ) {\n\t\t\t\t\tbuf.append( '(' )\n\t\t\t\t\t\t\t.append( columnName )\n\t\t\t\t\t\t\t.append( \" is null or \" )\n\t\t\t\t\t\t\t.append( columnName )\n\t\t\t\t\t\t\t.append( \" in (\" );\n\t\t\t\t}\n\t\t\t\telse {\n\t\t\t\t\tbuf.append( columnName ).append( \" in (\" );\n\t\t\t\t}\n\n\t\t\t\tfor ( Object value : values ) {\n\t\t\t\t\tif ( !NULL.equals( value ) ) {\n\t\t\t\t\t\tbuf.append( value );","sourceCodeStart":77,"sourceCodeEnd":113,"githubUrl":"https://github.com/hibernate/hibernate-orm/blob/fad1729dce015f908198d57a8d80274a30f905a5/hibernate-core/src/main/java/org/hibernate/sql/InFragment.java#L77-L113","documentation":"InFragment is the legacy builder for SQL IN-list restrictions (used by old Criteria translators and discriminator restrictions). It understands a NULL sentinel — rendered as 'col is null or col in (...)' — but a NOT_NULL sentinel is meaningless inside an IN expression, so encountering it in the default branch throws IllegalArgumentException. The restriction as composed is logically impossible.","triggerScenarios":"Legacy Criteria/Criterion code or custom restrictors plumbing InFragment.NOT_NULL through addValue(); discriminator-based filters reusing InFragment constants; ported code that used NOT NULL semantics from a different fragment type.","commonSituations":"Maintaining pre-JPA-Criteria code paths; custom dialect or restriction helpers built on org.hibernate.sql fragments; copying InFragment usage from old forum code.","solutions":["Remove the NOT_NULL sentinel from the value list — never pass InFragment.NOT_NULL to an IN fragment","Express 'is not null' with a dedicated isNotNull restriction/condition instead of the IN list","Migrate legacy Hibernate Criteria usage to JPA Criteria or JPAQL, which handle null semantics explicitly"],"exampleFix":"// before (legacy internal fragment usage)\nInFragment frag = new InFragment();\nfrag.setColumnName(\"region_code\");\nfrag.addValue(InFragment.NOT_NULL); // IllegalArgumentException\n\n// after\nfrag.addValue(\"EMEA\").addValue(\"APAC\");\n// and use a separate \"region_code is not null\" condition where needed","handlingStrategy":"validation","validationCode":"// if you must use InFragment, filter invalid sentinels first\nfor (Object value : values) {\n    if (!InFragment.NOT_NULL.equals(value)) {\n        fragment.addValue(value); // NULL is fine; NOT_NULL never is\n    }\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Never pass InFragment.NOT_NULL to an IN-list fragment","Express 'is not null' with a dedicated condition, not the IN restriction","Migrate legacy Criteria code to JPA Criteria to avoid raw fragment plumbing"],"tags":["legacy-criteria","sql-generation","query-api"],"backgroundTag":"invalid-query-restriction","analyzedSha":"fad1729dce015f908198d57a8d80274a30f905a5","analyzedAt":"2026-08-22T04:13:57.527Z","schemaVersion":2},"datasetVersion":"2026-08-22T09:17:25.309Z"}