{"record":{"id":"ea16dbd092b49f00","repo":"hibernate/hibernate-orm","slug":"type-to-register-cannot-be-null","errorCode":null,"errorMessage":"Type to register cannot be null","messagePattern":"Type to register cannot be null","errorType":"exception","errorClass":"HibernateException","httpStatus":null,"severity":"error","filePath":"hibernate-core/src/main/java/org/hibernate/type/BasicTypeRegistry.java","lineNumber":381,"sourceCode":"\n\t// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\t// Mutations\n\n\tpublic void register(BasicType<?> type) {\n\t\tregister( type, type.getRegistrationKeys() );\n\t}\n\n\tpublic void register(BasicType<?> type, String key) {\n\t\tregister( type, new String[]{ key } );\n\t}\n\n\tpublic void register(BasicType<?> type, String... keys) {\n\t\tif ( ! isPrimed() ) {\n\t\t\tthrow new IllegalStateException( \"BasicTypeRegistry not yet primed. Calls to `#register` not valid until after primed\" );\n\t\t}\n\n\t\tif ( type == null ) {\n\t\t\tthrow new HibernateException( \"Type to register cannot be null\" );\n\t\t}\n\n\t\t// explicit registration keys\n\t\tif ( isEmpty( keys ) ) {\n\t\t\tCORE_LOGGER.typeDefinedNoRegistrationKeys( type );\n\t\t}\n\t\telse {\n\t\t\tapplyRegistrationKeys( type, keys );\n\t\t}\n\t}\n\n\tpublic <T> CustomType<T> register(UserType<T> type, String... keys) {\n\t\tfinal var customType = new CustomType<>( type, keys, typeConfiguration );\n\t\tregister( customType );\n\t\treturn customType;\n\t}\n\n\tpublic void unregister(String... keys) {","sourceCodeStart":363,"sourceCodeEnd":399,"githubUrl":"https://github.com/hibernate/hibernate-orm/blob/fad1729dce015f908198d57a8d80274a30f905a5/hibernate-core/src/main/java/org/hibernate/type/BasicTypeRegistry.java#L363-L399","documentation":"BasicTypeRegistry.register(BasicType<?>, String...) (BasicTypeRegistry.java:375-385) guards its first argument and throws HibernateException 'Type to register cannot be null' when null is passed. The registry is populated at bootstrapping and extended through TypeContributor SPIs or MetadataBuilder type contributions, so this error means some contribution path handed null into register - usually a lookup or factory step that returned null upstream.","triggerScenarios":"A custom org.hibernate.boot.model.TypeContributor calling typeContributions.contributeBasicType(null) or register(null, \"mykey\"); MetadataBuilder.applyBasicType(null); programmatic BasicTypeRegistry.register(null, ...) after the registry is primed; a type produced conditionally (e.g. only when a dialect feature exists) being contributed unconditionally.","commonSituations":"Optional integrations that contribute a type only if an optional dependency is present and pass null otherwise; copy-pasted TypeContributor code where the constructor of the type throws or the field is not initialized; ordering issues where a contributor depends on another contributor having registered a type first.","solutions":["Ensure the BasicType instance is constructed before contributing it; never pass a possibly-null value into contributeBasicType/register.","If the type is optional, guard the contribution with an existence check and contribute nothing when unavailable.","If you depended on another contributor's type, look it up after bootstrap (Metadata.getDatabase/TypeConfiguration) instead of expecting it during contribution.","Add a unit test that runs your TypeContributor against a StandardServiceRegistry to catch null contributions at build time."],"exampleFix":"// before\npublic class MyTypeContributor implements TypeContributor {\n    public void contribute(TypeContributions c, ServiceRegistry r) {\n        c.contributeBasicType(findType()); // findType() may return null\n    }\n}\n\n// after\npublic class MyTypeContributor implements TypeContributor {\n    public void contribute(TypeContributions c, ServiceRegistry r) {\n        BasicType<?> t = findType();\n        if (t != null) {\n            c.contributeBasicType(t);\n        }\n    }\n}","handlingStrategy":"validation","validationCode":"public void contribute(TypeContributions c, ServiceRegistry r) {\n    BasicType<?> type = resolveType(); // may fail\n    if (type == null) {\n        return; // contribute nothing rather than null\n    }\n    c.contributeBasicType(type);\n}","typeGuard":"static boolean isRegisterable(BasicType<?> t) {\n    return t != null;\n}","tryCatchPattern":"try {\n    registry.register(type, keys);\n} catch (HibernateException e) {\n    if (\"Type to register cannot be null\".equals(e.getMessage())) {\n        log.warn(\"Skipping null basic type for keys {}\", (Object[]) keys);\n        return;\n    }\n    throw e;\n}","preventionTips":["Null-check every value produced by lookups before passing it to type-contribution APIs.","Keep TypeContributors side-effect free and covered by a bootstrap unit test."],"tags":["hibernate","type-registry","type-contributor","null-argument","bootstrap"],"backgroundTag":"null-argument-validation","analyzedSha":"fad1729dce015f908198d57a8d80274a30f905a5","analyzedAt":"2026-08-22T04:13:57.527Z","schemaVersion":2},"datasetVersion":"2026-08-22T09:17:25.309Z"}