hibernate/hibernate-orm · error · NullPointerException
null passed to Session.evict()
Error message
null passed to Session.evict()
What it means
DefaultEvictEventListener.onEvict() rejects a null argument with NullPointerException('null passed to Session.evict()'). evict() detaches one specific managed entity; passing null is a caller programming error, and Hibernate fails fast with an explicit message instead of silently ignoring the call.
Source
Thrown at hibernate-core/src/main/java/org/hibernate/event/internal/DefaultEvictEventListener.java:45
*
* @author Steve Ebersole
*/
public class DefaultEvictEventListener implements EvictEventListener {
/**
* Handle the given evict event.
*
* @param event The evict event to be handled.
*
*/
@Override
public void onEvict(@Nonnull EvictEvent event) {
final var source = event.getSession();
final var persistenceContext = source.getPersistenceContextInternal();
final Object object = event.getObject();
//noinspection ConstantValue
if ( object == null ) {
throw new NullPointerException( "null passed to Session.evict()" );
}
final var lazyInitializer = extractLazyInitializer( object );
if ( lazyInitializer != null ) {
final Object id = lazyInitializer.getInternalIdentifier();
if ( id == null ) {
throw new IllegalArgumentException( "Could not determine identifier of proxy passed to evict()" );
}
final var persister =
source.getFactory().getMappingMetamodel()
.getEntityDescriptor( lazyInitializer.getEntityName() );
final var key = source.generateEntityKey( id, persister );
final var holder = persistenceContext.detachEntity( key );
// if the entity has been evicted then its holder is null
if ( holder != null && !lazyInitializer.isUninitialized() ) {
final Object entity = holder.getEntity();
if ( entity != null ) {
final var entry = persistenceContext.removeEntry( entity );
doEvict( entity, key, entry.getPersister(), event.getSession() );View on GitHub (pinned to fad1729dce)
Solutions
- Null-check the reference before evict/detach
- Use Objects.requireNonNull(entity, ...) to fail with your own message at the correct call site
- Reconsider whether evict() should run at all for optional references — it only applies to managed entities
- Guard loops that evict collections with filter(Objects::nonNull)
Example fix
// before
session.evict(maybeCustomer); // maybeCustomer may be null
// after
if (maybeCustomer != null) {
session.evict(maybeCustomer);
} Defensive patterns
Strategy: validation
Validate before calling
java.util.Objects.requireNonNull(entity, "entity to evict must not be null"); session.evict(entity);
Type guard
static boolean evictable(Object o) {
return o != null;
} Prevention
- Null-check before every evict()/detach() call
- Guard optional lookups: session.find(...) results can be null
- Filter nulls before evicting from collections
- Fail fast with requireNonNull at the source rather than deep in Hibernate
When it happens
Trigger: Session.evict(null) or EntityManager.detach(null) — typically a null flowing from an optional lookup, Map.get() miss, or unwrapped Optional into the detach call.
Common situations: Cleanup code evicting entities from a map of optional results; helper methods that evict 'previous' entities when no previous exists; null returned by find() feeding an unconditional evict.
Related errors
- null object passed to getCurrentLockMode()
- Unrecognized JPA persistence.xml XSD version : `{}`
- Unrecognized JPA orm.xml XSD version : `{}`
- Cannot lazily initialize collection
- Illegal attempt to associate a collection with two open sess
AI-assisted analysis of hibernate/hibernate-orm@fad1729dce (2026-08-22).
Data as JSON: /api/errors/2bd34529d926acc7.
Report an issue: GitHub.