hibernate/hibernate-orm · error · IllegalStateException
Illegal to add BasicJavaType with null Java type
Error message
Illegal to add BasicJavaType with null Java type
What it means
While priming the JavaTypeRegistry, Hibernate rejects any JavaType whose getJavaType() returns null. addBaselineDescriptor(JavaType) requires the descriptor to know its own Java type because the registry is keyed by type name; a null-typed descriptor makes registration impossible and throws IllegalStateException.
Source
Thrown at hibernate-core/src/main/java/org/hibernate/type/descriptor/java/spi/JavaTypeRegistry.java:55
private static final Logger LOG = Logger.getLogger( JavaTypeRegistry.class );
private final TypeConfiguration typeConfiguration;
private final ConcurrentHashMap<String, JavaType<?>> descriptorsByTypeName = new ConcurrentHashMap<>();
public JavaTypeRegistry(TypeConfiguration typeConfiguration) {
this.typeConfiguration = typeConfiguration;
JavaTypeBaseline.prime( this );
}
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// baseline descriptors
@Override
public void addBaselineDescriptor(JavaType<?> descriptor) {
final var javaType = descriptor.getJavaType();
if ( javaType == null ) {
throw new IllegalStateException( "Illegal to add BasicJavaType with null Java type" );
}
addBaselineDescriptor( javaType, descriptor );
}
@Override
public void addBaselineDescriptor(Type describedJavaType, JavaType<?> descriptor) {
performInjections( descriptor );
descriptorsByTypeName.put( describedJavaType.getTypeName(), descriptor );
}
private void performInjections(JavaType<?> descriptor) {
if ( descriptor instanceof TypeConfigurationAware typeConfigurationAware ) {
// would be nice to make the JavaType for an entity, e.g., aware of the TypeConfiguration
typeConfigurationAware.setTypeConfiguration( typeConfiguration );
}
}
View on GitHub (pinned to fad1729dce)
Solutions
- Construct the descriptor with its Class: super(MyType.class)
- Override getJavaType()/getJavaTypeClass() to return a non-null Type/Class
- Use the two-argument overload addBaselineDescriptor(Type, JavaType) to supply the described type explicitly
- If the type is generic, register a ParameterizedJavaType or pass the raw Class instead of null
Example fix
// before
public class MyTypeJavaType extends AbstractClassJavaType<MyType> {
public MyTypeJavaType() { super(null); } // getJavaType() == null -> IllegalStateException
}
// after
public class MyTypeJavaType extends AbstractClassJavaType<MyType> {
public MyTypeJavaType() { super(MyType.class); }
} Defensive patterns
Strategy: validation
Validate before calling
static void assertRegistrable(JavaType<?> descriptor) {
if (descriptor.getJavaType() == null)
throw new IllegalStateException(
"descriptor " + descriptor + " has null Java type; register with addBaselineDescriptor(Type, JavaType)");
}
// call before registry.addBaselineDescriptor(descriptor) Type guard
static boolean registrable(JavaType<?> descriptor) {
return descriptor.getJavaType() != null;
} Try / catch
try {
registry.addBaselineDescriptor(descriptor);
} catch (IllegalStateException e) {
// log which contributor supplied the null-typed descriptor and skip it with a warning
LOG.warn("Skipping null-typed descriptor from contributor: {}", descriptor, e);
} Prevention
- Always pass the represented Class to JavaType constructors
- Unit-test custom TypeContributors by priming a fresh TypeConfiguration
- Use addBaselineDescriptor(Type, JavaType) when the described type is generic
When it happens
Trigger: A TypeContributor or integrator calling typeConfiguration.getJavaTypeRegistry().addBaselineDescriptor(descriptor) where the descriptor was built without a Class/Type (null passed to the constructor) or does not override getJavaType(); custom AbstractJavaType subclasses for generic types where no Class object is available at construction.
Common situations: Custom integrations registering descriptors of parameterized types; copy-pasted descriptor scaffolding with a null super(...) argument; upgrades where getJavaType() became nullable and old code stopped overriding it.
Related errors
- Type registration was corrupted for: " + javaClass.getName()
- Unable to determine SQL type name for column '%s' of table '
- Class '" + typeName + "' does not implement '" + supertype.g
- Could not format discriminator value to SQL string
- Unknown unwrap conversion requested: " + type.getTypeName()
AI-assisted analysis of hibernate/hibernate-orm@fad1729dce (2026-08-22).
Data as JSON: /api/errors/f9e1283cb336acdf.
Report an issue: GitHub.