hibernate/hibernate-orm · error · UnresolvableObjectException

No row with the given identifier exists for entity " + infoS

Error message

No row with the given identifier exists for entity " + infoString( entityName, identifier )

What it means

UnresolvableObjectException (with the full message "No row with the given identifier exists for entity <Entity>#<id>", assembled in getMessage() at UnresolvableObjectException.java:61) is thrown when a load by identifier finds no database row. The throwIfNull factory (UnresolvableObjectException.java:44-49) is invoked by loader code after a row comes back null; its subclass ObjectNotFoundException covers the lazy-proxy variant of the same situation. It almost always means the row was deleted by another transaction, or the id simply does not exist, while your persistence context still references it.

Source

Thrown at hibernate-core/src/main/java/org/hibernate/UnresolvableObjectException.java:47

	protected UnresolvableObjectException(String message, Object identifier, String clazz) {
		super( message );
		this.identifier = identifier;
		this.entityName = clazz;
	}

	/**
	 * Factory method for building and throwing an {@code UnresolvableObjectException} if the entity is null.
	 *
	 * @param entity The entity to check for nullness
	 * @param identifier The identifier of the entity
	 * @param entityName The name of the entity
	 *
	 * @throws UnresolvableObjectException Thrown if entity is null
	 */
	public static void throwIfNull(Object entity, Object identifier, String entityName)
			throws UnresolvableObjectException {
		if ( entity == null ) {
			throw new UnresolvableObjectException( identifier, entityName );
		}
	}

	public Object getIdentifier() {
		return identifier;
	}

	public String getEntityName() {
		return entityName;
	}

	@Override
	public String getMessage() {
		return super.getMessage() + " for entity " + infoString( entityName, identifier );
	}

}

View on GitHub (pinned to fad1729dce)

Solutions

  1. Switch from load()/getReference() to get()/find() and null-check the result - find() returns null instead of throwing for a missing row
  2. If you must keep the lazy reference, wrap first access in try/catch for ObjectNotFoundException (subclass of UnresolvableObjectException) and recover by treating the entity as deleted
  3. Re-fetch the id's existence with a cheap exists-query before dereferencing stale references in long conversations
  4. For concurrent-delete hotspots, consider a short pessimistic lock when loading so the row cannot vanish mid-transaction

Example fix

// before - throws UnresolvableObjectException/ObjectNotFoundException when the row is gone
Order order = session.load(Order.class, orderId);
order.getTotal();

// after - returns null for a missing row, handle explicitly
Order order = session.get(Order.class, orderId);
if (order == null) {
    return ResponseEntity.notFound().build();
}
Defensive patterns

Strategy: try-catch

Validate before calling

// before dereferencing a possibly-stale reference, verify existence with find()
Order order = em.find(Order.class, orderId);
if (order == null) {
    // handle 'row gone' as a normal business case
}

Try / catch

try {
    order.getTotal(); // lazy access on a load()/getReference() proxy
} catch (ObjectNotFoundException | UnresolvableObjectException e) {
    // treat as deleted: drop from UI / return 410 Gone
}

Prevention

When it happens

Trigger: session.load()/EntityManager.getReference() returning a proxy whose underlying row is deleted before first access; loading an association whose target row was removed concurrently; calling internal persister loads with a stale identifier taken from a detached object or a cached reference.

Common situations: Long-lived optimistic conversations where another user/session deleted the row; admin cleanup jobs removing rows still referenced by in-flight requests; UI code caching ids past their lifetime; tests that assume seeded data that was rolled back.

Understand the failure class

Background: "Not found" and "does not exist" errors: why "Task not found", "No such folder", and "Can't find" fire when a lookup comes back empty — this error's family across 14 libraries.

Related errors


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