hibernate/hibernate-orm · error · UnsupportedOperationException

Cannot add primary key constraint in Cloud Spanner.

Error message

Cannot add primary key constraint in Cloud Spanner.

What it means

SpannerDialect.getAddPrimaryKeyConstraintString() throws UnsupportedOperationException because Cloud Spanner does not support ALTER TABLE ... ADD PRIMARY KEY — a primary key must be declared inline in CREATE TABLE. This guard fires whenever Hibernate's schema migrator tries to emit an add-PK alter statement, which on Spanner is always invalid. It signals a mapping/tooling path that expects additive DDL Spanner cannot perform.

Source

Thrown at hibernate-core/src/main/java/org/hibernate/dialect/SpannerDialect.java:1215

	public String getCurrentSchemaCommand() {
		throw new UnsupportedOperationException(
				"No current schema syntax supported by " + getClass().getName() );
	}

	@Override
	public SchemaNameResolver getSchemaNameResolver() {
		// Spanner does not have a notion of database name schemas, so return "".
		return (connection, dialect) -> "";
	}

	@Override
	public boolean qualifyIndexName() {
		return false;
	}

	@Override
	public String getAddPrimaryKeyConstraintString(String constraintName) {
		throw new UnsupportedOperationException( "Cannot add primary key constraint in Cloud Spanner." );
	}

	// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
	// Lock acquisition functions

	@Override
	public LockingSupport getLockingSupport() {
		return SPANNER_LOCKING_SUPPORT;
	}

	@Override
	public LockingClauseStrategy getLockingClauseStrategy(QuerySpec querySpec, LockOptions lockOptions) {
		if ( getPessimisticLockStyle() != PessimisticLockStyle.CLAUSE || lockOptions == null ) {
			return NON_CLAUSE_STRATEGY;
		}
		final var lockKind = PessimisticLockKind.interpret( lockOptions.getLockMode() );
		if ( lockKind == PessimisticLockKind.NONE ) {
			return NON_CLAUSE_STRATEGY;

View on GitHub (pinned to fad1729dce)

Solutions

  1. Ensure every @Entity declares @Id/@EmbeddedId so the CREATE TABLE generated for Spanner includes PRIMARY KEY inline, and recreate the table rather than altering it.
  2. Replace hbm2ddl schema update with explicit migrations using Cloud Spanner DDL (CREATE TABLE ... PRIMARY KEY (...)) via the Spanner migration tooling.
  3. If you are issuing alters programmatically, check `dialect.getAddPrimaryKeyConstraintString` availability or skip PK alters for Spanner before calling.
  4. For existing tables needing a new key, create a new table, copy data, and swap — Spanner cannot retrofit a PK.

Example fix

// before: migrate later with alter
// alter table orders add constraint pk_orders primary key (id) -- Unsupported

// after: key declared inline at create time
@Entity
public class Order {
  @Id String id;
  ...
}
// -> create table orders (id string not null, ..., ) primary key (id)
Defensive patterns

Strategy: fallback

Validate before calling

if (dialect instanceof SpannerDialect) {
  // verify PK exists inline in table DDL instead of planning an ALTER
  Table t = metadata.getEntityBinding(Entity.class.getName()).getTable();
  if (t.getPrimaryKey() == null || t.getPrimaryKey().columnSpan() == 0) {
    throw new IllegalStateException("Spanner requires PRIMARY KEY inline in CREATE TABLE for " + t.getName());
  }
}

Try / catch

try {
  migrator.performMigration(migration, executionOptions, target);
} catch (UnsupportedOperationException e) {
  if (e.getMessage().contains("primary key")) { /* recreate table with inline PK and copy data instead */ }
  throw e;
}

Prevention

When it happens

Trigger: SchemaUpdate/hbm2ddl alter passes where an entity lacks an inline PK at create time or a constraint is added later (e.g. `@PrimaryKeyJoinColumn` handling or manual AlterTable commands); executing `new SchemaMigrator()` that generates 'alter table T add constraint ... primary key' against Spanner; secondary mapping mistakes where the key is not part of the CREATE TABLE definition.

Common situations: Running hibernate.hbm2ddl.auto=update on evolving Spanner schemas; migrations authored for databases that permit deferred PK addition; entities whose identifier is only discovered as a constraint by the tooling rather than declared in the table DDL.

Related errors


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