hibernate/hibernate-orm · error · IllegalArgumentException
Entity may not be null
Error message
Entity may not be null
What it means
IllegalArgumentException from the DeleteEvent constructor (this(object, source) chain): session.remove(null)/session.delete(null) attempts to build a DeleteEvent with a null object, violating the @Nonnull contract, and is rejected before any listener runs. Passing null to a delete is always a caller bug — usually a null that leaked in from a failed lookup or an optional relation.
Source
Thrown at hibernate-core/src/main/java/org/hibernate/event/spi/DeleteEvent.java:31
* @apiNote This class predates JPA, and today should
* really be named {@code RemoveEvent}.
*
* @author Steve Ebersole
*
* @see org.hibernate.Session#remove
*/
public class DeleteEvent extends AbstractSessionEvent {
private final Object object;
private String entityName;
private boolean cascadeDeleteEnabled;
// TODO: The removeOrphan concept is a temporary "hack" for HHH-6484.
// This should be removed once action/task ordering is improved.
private boolean orphanRemovalBeforeUpdates;
public DeleteEvent(@Nonnull Object object, @Nonnull EventSource source) {
super(source);
if (object == null) {
throw new IllegalArgumentException( "Entity may not be null" );
}
this.object = object;
}
public DeleteEvent(@Nullable String entityName, @Nonnull Object object, @Nonnull EventSource source) {
this(object, source);
this.entityName = entityName;
}
public DeleteEvent(@Nullable String entityName, @Nonnull Object object, boolean cascadeDeleteEnabled, @Nonnull EventSource source) {
this(object, source);
this.entityName = entityName;
this.cascadeDeleteEnabled = cascadeDeleteEnabled;
}
public DeleteEvent(@Nullable String entityName, @Nonnull Object object, boolean cascadeDeleteEnabled,
boolean orphanRemovalBeforeUpdates, @Nonnull EventSource source) {
this(object, source);View on GitHub (pinned to fad1729dce)
Solutions
- Null-check before calling remove/delete — a null target usually means 'nothing to delete', which is a no-op, not an error
- Trace the null to its origin (find() miss, unset optional relation) and fix or explicitly skip at that point
- Prefer delete-by-id patterns (e.g. Spring Data repository.deleteById or a bulk JPQL delete) that validate the id instead of the entity
Example fix
// before User user = userRepository.findByIdOrNull(id); em.remove(user); // id absent -> user == null -> Entity may not be null // after Optional.ofNullable(user).ifPresent(em::remove);
Defensive patterns
Strategy: validation
Validate before calling
if (user != null) {
em.remove(user);
}
// or: Optional.ofNullable(user).ifPresent(em::remove); Type guard
null
Try / catch
null
Prevention
- Guard all remove/delete entry points with null checks — null means nothing to delete
- Prefer id-based delete methods (deleteById) that validate the identifier
- Mark entity parameters @NonNull and use static analysis to catch nullable flows
When it happens
Trigger: session.delete(null) or EntityManager.remove(null); helper methods like deleteByIdHelper(entity) invoked with a null found by a query/em.find; deleting an optional association's target that was never set.
Common situations: Optional-entity flows where a missing row becomes null and is passed to remove; cleaning up relations where one side is legitimately absent (should be skipped, not deleted); mock-based tests passing null; JPA spec mandates IllegalArgumentException for remove(null), so Hibernate fails fast with this message.
Related errors
- Attempted to refresh null
- Named query definition is null
- Named native query definition object is null
- Result-set mapping was null
- Import name or entity name is null
AI-assisted analysis of hibernate/hibernate-orm@fad1729dce (2026-08-22).
Data as JSON: /api/errors/7d8493b6894ada00.
Report an issue: GitHub.