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

  1. Null-check before calling remove/delete — a null target usually means 'nothing to delete', which is a no-op, not an error
  2. Trace the null to its origin (find() miss, unset optional relation) and fix or explicitly skip at that point
  3. 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

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


AI-assisted analysis of hibernate/hibernate-orm@fad1729dce (2026-08-22). Data as JSON: /api/errors/7d8493b6894ada00. Report an issue: GitHub.