hibernate/hibernate-orm · error · MappingException

${getClass().getName()} does not support selecting the last

Error message

${getClass().getName()} does not support selecting the last generated identity value

What it means

Spanner (Google Cloud Spanner) supports identity-style columns ('generated by default as identity (bit_reversed_positive)'), but it cannot return the last generated value through a separate SELECT statement. SpannerIdentityColumnSupport.getIdentitySelectString therefore throws MappingException '<class> does not support selecting the last generated identity value' whenever Hibernate needs that identity-retrieval SQL instead of using JDBC getGeneratedKeys().

Source

Thrown at hibernate-core/src/main/java/org/hibernate/dialect/identity/SpannerIdentityColumnSupport.java:24

import org.hibernate.MappingException;

/**
 * Identity column support for Spanner.
 */
public class SpannerIdentityColumnSupport extends IdentityColumnSupportImpl {
	public static final SpannerIdentityColumnSupport INSTANCE = new SpannerIdentityColumnSupport();

	private SpannerIdentityColumnSupport() {}

	@Override
	public boolean supportsIdentityColumns() {
		return true;
	}

	@Override
	public String getIdentitySelectString(String table, String column, int type) throws MappingException {
		throw new MappingException(
				getClass().getName() + " does not support selecting the last generated identity value");
	}

	@Override
	public String getIdentityColumnString(int type) {
		return "not null generated by default as identity (bit_reversed_positive)";
	}
}

View on GitHub (pinned to fad1729dce)

Solutions

  1. Keep hibernate.jdbc.use_get_generated_keys=true (default) so Spanner keys are returned via JDBC getGeneratedKeys instead of an identity SELECT
  2. Prefer client-assigned keys on Spanner (e.g. @GeneratedValue(strategy = GenerationType.UUID) or application-generated ids), which avoids retrieval entirely
  3. Use a sequence/table generator if the schema allows it
  4. Catch MappingException at bootstrap as an explicit signal that the current key-retrieval path is incompatible with Spanner, then adjust configuration

Example fix

// before - forces identity select fallback on Spanner
hibernate.jdbc.use_get_generated_keys=false

// after
hibernate.jdbc.use_get_generated_keys=true
// or avoid retrieval entirely:
@Id @GeneratedValue(strategy = GenerationType.UUID)
private UUID id;
Defensive patterns

Strategy: fallback

Validate before calling

// Ensure key retrieval can work on Spanner before persisting
boolean getGeneratedKeys = sessionFactory.getSessionFactoryOptions().isGetGeneratedKeysEnabled();
if (!getGeneratedKeys && usesIdentityGeneration(metadata)) {
    throw new IllegalStateException("Spanner cannot SELECT the last identity value - enable getGeneratedKeys or assign ids client-side");
}

Try / catch

try {
    session.persist(person);
    session.flush();
}
catch (MappingException e) {
    if (e.getMessage().contains("does not support selecting the last generated identity value")) {
        throw new UnsupportedOperationException("Assign ids client-side (UUID) on Spanner", e);
    }
    throw e;
}

Prevention

When it happens

Trigger: With the Spanner dialect, persisting an entity with an identity-generated key in a code path that requests the identity select string - typically when getGeneratedKeys is disabled (hibernate.jdbc.use_get_generated_keys=false) or unavailable, so Hibernate falls back to appending/selecting the identity value. Also hit by code that directly calls dialect.getIdentityColumnSupport().getIdentitySelectString(...).

Common situations: Porting an application to Cloud Spanner while keeping GenerationType.IDENTITY; disabling JDBC getGeneratedKeys globally for performance or driver quirks; older Hibernate versions where Spanner key retrieval took a different path; custom insert logic that asks the persister for a post-insert select.

Related errors


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