hibernate/hibernate-orm · error · HibernateException

Duplicate identifier in table (%s) - %s#%s

Error message

Duplicate identifier in table (%s) - %s#%s

What it means

When a single insert/update/delete reports more affected rows than expected (TooManyRowsAffectedException), ModelMutationHelper wraps it as HibernateException 'Duplicate identifier in table (T) - Role#id': the database updated/deleted several rows for one identifier, which by Hibernate's mapping should be impossible for a correctly-keyed table.

Source

Thrown at hibernate-core/src/main/java/org/hibernate/engine/jdbc/mutation/internal/ModelMutationHelper.java:77

					statementDetails.getStatement(),
					batchPosition,
					statementDetails.getSqlString()
			);
			return true;
		}
		catch (StaleStateException e) {
			if ( !statementDetails.getMutatingTableDetails().isOptional() && affectedRowCount == 0 ) {
				final String fullPath = mutationTarget.getNavigableRole().getFullPath();
				final var statistics = sessionFactory.getStatistics();
				if ( statistics.isStatisticsEnabled() ) {
					statistics.optimisticFailure( fullPath );
				}
				throw new StaleObjectStateException( fullPath, id, e );
			}
			return false;
		}
		catch (TooManyRowsAffectedException e) {
			throw new HibernateException(
					String.format(
							Locale.ROOT,
							"Duplicate identifier in table (%s) - %s#%s",
							statementDetails.getMutatingTableDetails().getTableName(),
							mutationTarget.getNavigableRole().getFullPath(),
							id
					)
			);
		}
		catch (Throwable t) {
			return false;
		}
	}

	public static PreparedStatementGroup toPreparedStatementGroup(
			MutationType mutationType,
			MutationTarget<?,?> mutationTarget,
			GeneratedValuesMutationDelegate delegate,

View on GitHub (pinned to fad1729dce)

Solutions

  1. Find the duplicates: SELECT id, COUNT(*) FROM <table> GROUP BY id HAVING COUNT(*) > 1, then repair/delete the extra rows
  2. Restore the primary key / unique constraints on the affected table so duplicates cannot recur
  3. Verify the entity mapping is not accidentally mapping two entities to the same table row space (shared tables, @Tables/@Table annotations)

Example fix

-- diagnosis
SELECT id, COUNT(*) FROM child_table GROUP BY id HAVING COUNT(*) > 1;
-- repair
DELETE FROM child_table WHERE rowid NOT IN (SELECT MIN(rowid) FROM child_table GROUP BY id);
ALTER TABLE child_table ADD PRIMARY KEY (id);
Defensive patterns

Strategy: validation

Validate before calling

// pre-flight duplicate check on id columns used by Hibernate
SELECT id, COUNT(*) FROM child_table GROUP BY id HAVING COUNT(*) > 1;
-- add PK constraints so the invariant cannot regress
ALTER TABLE child_table ADD CONSTRAINT pk_child PRIMARY KEY (id);

Try / catch

try {
    session.merge(entity);
    session.flush();
}
catch (HibernateException e) {
    if (e.getMessage() != null && e.getMessage().startsWith("Duplicate identifier in table")) {
        // run the duplicate-detection query and page an on-call data fix
    }
}

Prevention

When it happens

Trigger: The mutated table physically contains multiple rows with the same primary key value — typically secondary tables or JOINED-inheritance child tables whose PK/FK constraint is missing or was dropped — or data was bulk-imported/merged creating duplicates, so an UPDATE ... WHERE id = ? hits several rows.

Common situations: Bulk loads into inheritance tables without enforced primary keys; constraints dropped 'temporarily' in prod and never restored; manual data fixes that inserted duplicate child rows; database restores that duplicated rows.

Related errors


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