hibernate/hibernate-orm · error · HibernateException

The database returned no natively generated values : {}

Error message

The database returned no natively generated values : {}

What it means

After inserting/updating a row whose values are generated by the database (identity ids, @GeneratedColumn columns, defaults read back via RETURNING/getGeneratedKeys), Hibernate consumes the statement's generated-values result. If that result contains no row at all, this HibernateException is thrown — the dialect/driver expected retrievable generated values but the execution returned none.

Source

Thrown at hibernate-core/src/main/java/org/hibernate/generator/values/internal/GeneratedValuesHelper.java:174

				mappingProducer.resolve( directResultSetAccess, influencers, factory ),
				null,
				executionContext
		);
		final var valuesProcessingState =
				new JdbcValuesSourceProcessingStateStandardImpl( executionContext, NO_OPTIONS );
		final RowReader<Object[]> rowReader = ResultsHelper.createRowReader(
				factory,
				RowTransformerArrayImpl.instance(),
				Object[].class,
				jdbcValues
		);
		final var rowProcessingState =
				new RowProcessingStateStandardImpl( valuesProcessingState, executionContext, rowReader, jdbcValues );
		final List<Object[]> results =
				ListResultsConsumer.<Object[]>instance( ListResultsConsumer.UniqueSemantic.NONE )
						.consume( jdbcValues, session, NO_OPTIONS, valuesProcessingState, rowProcessingState, rowReader );
		if ( results.isEmpty() ) {
			throw new HibernateException( "The database returned no natively generated values : "
											+ persister.getNavigableRole().getFullPath() );
		}
		return results.get( 0 );
	}

	/**
	 * Utility method that instantiates a {@link JdbcValuesMappingProducer} so it can be cached by the
	 * {@link GeneratedValuesMutationDelegate delegates} when they are instantiated.
	 *
	 * @param persister the current entity persister
	 * @param timing the timing of the mutation operation
	 * @param supportsArbitraryValues if we should process arbitrary (non-identifier) generated values
	 * @param supportsRowId if we should process {@link org.hibernate.metamodel.mapping.EntityRowIdMapping rowid}s
	 * {@code false} if we should retrieve the index through the column expression
	 *
	 * @return the instantiated jdbc values mapping producer
	 */
	public static GeneratedValuesMappingProducer createMappingProducer(

View on GitHub (pinned to fad1729dce)

Solutions

  1. Switch the identifier from IDENTITY to SEQUENCE (+ allocationSize) so ids are fetched before insert and no getGeneratedKeys/RETURNING roundtrip is needed
  2. If the table has a trigger, fix it so the generated columns are still returned (SQL Server: avoid result-set-eating trigger patterns)
  3. Upgrade the JDBC driver to a version known to return generated keys correctly (mssql-jdbc over jTDS, current Jaybird, current ojdbc)
  4. For view/INSTEAD OF trigger mappings, remove database-side generation annotations and read values explicitly after flush
  5. Verify the configured dialect matches your database version

Example fix

// before — identity + trigger on SQL Server returns no generated-keys row
@Id @GeneratedValue(strategy = GenerationType.IDENTITY)
Long id;

// after — sequence: id fetched before insert, no readback dependency
@Id @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "order_seq")
@SequenceGenerator(name = "order_seq", sequenceName = "order_seq", allocationSize = 50)
Long id;
Defensive patterns

Strategy: try-catch

Try / catch

try {
    session.persist(order);
    session.flush();
}
catch (HibernateException e) {
    if (e.getMessage() != null
            && e.getMessage().startsWith("The database returned no natively generated values")) {
        // the row may exist without a returned id: do NOT blind-retry the insert;
        // re-query by natural/unique key, or roll back and switch to sequence-based ids
        throw new GeneratedKeysUnavailableException(order, e);
    }
    throw e;
}

Prevention

When it happens

Trigger: INSERT on a table where the generated-values result comes back empty: SQL Server tables with triggers (the classic getGeneratedKeys case returning zero rows), PostgreSQL INSTEAD OF triggers on views suppressing the RETURNING row, older JDBC drivers (jTDS, old Jaybird/Firebird, old Oracle) that fail to return generated keys, or a dialect relying on RETURNING against a database that does not deliver it.

Common situations: Adding an audit trigger to a legacy table that already used GenerationType.IDENTITY; mapping entities onto views with INSTEAD OF triggers plus @GeneratedColumn; driver upgrades/downgrades; migration between identity and sequence strategies.

Related errors


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