hibernate/hibernate-orm · error · HibernateException

Duplicate row was found and

Error message

Duplicate row was found and `%s` was specified

What it means

Thrown by ListResultsConsumer.readUniqueAssert when a query runs under UniqueSemantic.ASSERT: every row read must be distinct, and results.addUnique detected a row equal (per the result JavaType) to one already collected. ASSERT is applied primarily by the internal by-id load plan (SingleIdLoadPlan uses ASSERT when a single result is expected), i.e. `EntityManager.find`/`session.find`, and only when the row reader has no collection initializers. Genuine duplicates for a primary-key load mean the mapping does not guarantee one row per id.

Solutions

  1. Fix the underlying data or mapping so at most one row exists per primary key (dedupe the view/table, add the missing unique constraint)
  2. For JOINED inheritance, delete the duplicate id rows from the extra subclass table(s) so each id lives in exactly one subclass
  3. Fix custom `@Loader`/`@SQLSelect` SQL to return a unique row (add the right predicate or `distinct` on the id)
  4. As a stopgap, load via a query with `UniqueSemantic`-tolerant semantics (e.g. a plain JPQL `where e.id = :id`) instead of `find()` to observe the duplicates, then fix the data

Example fix

// before: entity mapped to a view with duplicate ids -> em.find throws
Employee e = em.find(Employee.class, id);
// after: dedupe the view (SQL) so each id appears once, keep em.find
create view employee_v as select distinct on (id) * from employee_raw;
Defensive patterns

Strategy: validation

Validate before calling

// Prove the load key is unique before relying on em.find (e.g. for view-backed entities)
Long cnt = em.createQuery("select count(*) from EmployeeViewBacked e where e.businessKey = :k", Long.class)
             .setParameter("k", key).getSingleResult();
if (cnt != 1) throw new IllegalStateException("Load key not unique: " + key + " (" + cnt + " rows)");

Try / catch

catch (org.hibernate.HibernateException e) { if (e.getMessage() != null && e.getMessage().contains("Duplicate row was found")) { /* data issue: dedupe, fix view/inheritance/custom loader */ } throw e; }

Prevention

When it happens

Trigger: `em.find(Employee.class, id)` where the entity is mapped to a database view containing the id twice; JOINED inheritance with the same id present in two subclass tables; a custom `@Loader`/`@SQLSelect` returning the same id more than once; broken data where a 'unique' key used for loading is not actually unique.

Common situations: Read-only reporting entities mapped onto views without a unique key; denormalized tables feeding entity mappings; data corruption or manual inserts breaking subclass-table uniqueness; custom loader SQL with an accidental cross join duplicating rows.

Related errors


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

Appendix: source

Thrown at hibernate-core/src/main/java/org/hibernate/sql/results/spi/ListResultsConsumer.java:262

			RowReader<R> rowReader,
			Results<R> results) {
		int readRows = 0;
		while ( rowProcessingState.next() ) {
			results.add( rowReader.readRow( rowProcessingState ) );
			rowProcessingState.finishRowProcessing( true );
			readRows++;
		}
		return readRows;
	}

	private static <R> int readUniqueAssert(
			RowProcessingStateStandardImpl rowProcessingState,
			RowReader<R> rowReader,
			Results<R> results) {
		int readRows = 0;
		while ( rowProcessingState.next() ) {
			if ( !results.addUnique( rowReader.readRow( rowProcessingState ) ) ) {
				throw new HibernateException(
						String.format(
								Locale.ROOT,
								"Duplicate row was found and `%s` was specified",
								UniqueSemantic.ASSERT
						)
				);
			}
			rowProcessingState.finishRowProcessing( true );
			readRows++;
		}
		return readRows;
	}

	private static <R> int readUnique(
			RowProcessingStateStandardImpl rowProcessingState,
			RowReader<R> rowReader,
			Results<R> results) {
		int readRows = 0;

View on GitHub (pinned to fad1729dce)