{"record":{"id":"826be4102e66d3e5","repo":"hibernate/hibernate-orm","slug":"this-map-does-not-support-null-keys","errorCode":null,"errorMessage":"This map does not support null keys","messagePattern":"This map does not support null keys","errorType":"exception","errorClass":"NullPointerException","httpStatus":null,"severity":"error","filePath":"hibernate-core/src/main/java/org/hibernate/internal/util/collections/InstanceIdentityMap.java","lineNumber":148,"sourceCode":"\t}\n\n\t/**\n\t * {@inheritDoc}\n\t * @implNote This only works for {@link InstanceIdentity} keys, and it's inefficient\n\t * since we need to do a type check. Prefer using {@link #get(int, Object)}.\n\t */\n\t@Override\n\tpublic @Nullable V get(Object key) {\n\t\tif ( key instanceof InstanceIdentity instance ) {\n\t\t\treturn get( instance.$$_hibernate_getInstanceId(), instance );\n\t\t}\n\t\tthrow new ClassCastException( \"Provided key does not support instance identity\" );\n\t}\n\n\t@Override\n\tpublic @Nullable V put(K key, V value) {\n\t\tif ( key == null ) {\n\t\t\tthrow new NullPointerException( \"This map does not support null keys\" );\n\t\t}\n\n\t\tfinal int index = key.$$_hibernate_getInstanceId() - 1;\n\t\tif ( index < 0 ) {\n\t\t\tthrow new IllegalArgumentException( \"Instance ID must be a positive value\" );\n\t\t}\n\n\t\tfinal Map.Entry<K, V> old = set( index, new AbstractMap.SimpleImmutableEntry<>( key, value ) );\n\t\tif ( old == null ) {\n\t\t\tsize++;\n\t\t\treturn null;\n\t\t}\n\t\telse {\n\t\t\treturn old.getValue();\n\t\t}\n\t}\n\n\t/**","sourceCodeStart":130,"sourceCodeEnd":166,"githubUrl":"https://github.com/hibernate/hibernate-orm/blob/fad1729dce015f908198d57a8d80274a30f905a5/hibernate-core/src/main/java/org/hibernate/internal/util/collections/InstanceIdentityMap.java#L130-L166","documentation":"InstanceIdentityMap.put(K key, V value) rejects a null key immediately with NullPointerException and the message 'This map does not support null keys'. Entries are addressed by key.$$_hibernate_getInstanceId(), so a null key has no addressable identity — the map fails fast rather than masking the problem in a HashMap-like null bucket.","triggerScenarios":"put(null, value) — typically a key variable that was null-checked nowhere upstream: an entity reference that failed to load, a lookup that returned null, or a defensive default of null.","commonSituations":"Putting entities into instance-identity storage without checking whether the preceding load/find actually returned an object; Optional-unwrapping defaults of null; copy loops from another map that legitimately contained null keys.","solutions":["Null-check the key before put and skip or log the null case deliberately","Trace where the null entity came from — usually a session.get()/find() that returned null for a missing row","Never substitute null keys; if absence is meaningful, store a sentinel object or use a separate set"],"exampleFix":"// before\nmap.put( entity, state );\n// after\nif ( entity == null ) {\n    throw new IllegalArgumentException( \"entity must be loaded before insertion\" );\n}\nmap.put( entity, state );","handlingStrategy":"validation","validationCode":"if ( key == null ) {\n    // deliberate policy: skip, or fail with context\n    throw new IllegalArgumentException( \"key must be a loaded entity, got null\" );\n}\nmap.put( key, value );","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Null-check entity references right after session.get()/find() and before any map insertion","Never use null as a stand-in key; model absence explicitly","Enable -XX:+ShowMessageBoxOnError style strictness in tests via Objects.requireNonNull(key) at API boundaries"],"tags":["hibernate","null-key","map","validation","instance-identity"],"backgroundTag":"null-key-not-allowed","analyzedSha":"fad1729dce015f908198d57a8d80274a30f905a5","analyzedAt":"2026-08-22T04:13:57.527Z","schemaVersion":2},"datasetVersion":"2026-08-22T09:17:25.309Z"}