{"record":{"id":"9905bc843af7e574","repo":"hibernate/hibernate-orm","slug":"getclass-getname-does-not-support-selecting","errorCode":null,"errorMessage":"${getClass().getName()} does not support selecting the last generated identity value","messagePattern":"(.+?) does not support selecting the last generated identity value","errorType":"exception","errorClass":"MappingException","httpStatus":null,"severity":"error","filePath":"hibernate-core/src/main/java/org/hibernate/dialect/identity/SpannerIdentityColumnSupport.java","lineNumber":24,"sourceCode":"\nimport org.hibernate.MappingException;\n\n/**\n * Identity column support for Spanner.\n */\npublic class SpannerIdentityColumnSupport extends IdentityColumnSupportImpl {\n\tpublic static final SpannerIdentityColumnSupport INSTANCE = new SpannerIdentityColumnSupport();\n\n\tprivate SpannerIdentityColumnSupport() {}\n\n\t@Override\n\tpublic boolean supportsIdentityColumns() {\n\t\treturn true;\n\t}\n\n\t@Override\n\tpublic String getIdentitySelectString(String table, String column, int type) throws MappingException {\n\t\tthrow new MappingException(\n\t\t\t\tgetClass().getName() + \" does not support selecting the last generated identity value\");\n\t}\n\n\t@Override\n\tpublic String getIdentityColumnString(int type) {\n\t\treturn \"not null generated by default as identity (bit_reversed_positive)\";\n\t}\n}\n","sourceCodeStart":6,"sourceCodeEnd":33,"githubUrl":"https://github.com/hibernate/hibernate-orm/blob/fad1729dce015f908198d57a8d80274a30f905a5/hibernate-core/src/main/java/org/hibernate/dialect/identity/SpannerIdentityColumnSupport.java#L6-L33","documentation":"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().","triggerScenarios":"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(...).","commonSituations":"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.","solutions":["Keep hibernate.jdbc.use_get_generated_keys=true (default) so Spanner keys are returned via JDBC getGeneratedKeys instead of an identity SELECT","Prefer client-assigned keys on Spanner (e.g. @GeneratedValue(strategy = GenerationType.UUID) or application-generated ids), which avoids retrieval entirely","Use a sequence/table generator if the schema allows it","Catch MappingException at bootstrap as an explicit signal that the current key-retrieval path is incompatible with Spanner, then adjust configuration"],"exampleFix":"// before - forces identity select fallback on Spanner\nhibernate.jdbc.use_get_generated_keys=false\n\n// after\nhibernate.jdbc.use_get_generated_keys=true\n// or avoid retrieval entirely:\n@Id @GeneratedValue(strategy = GenerationType.UUID)\nprivate UUID id;","handlingStrategy":"fallback","validationCode":"// Ensure key retrieval can work on Spanner before persisting\nboolean getGeneratedKeys = sessionFactory.getSessionFactoryOptions().isGetGeneratedKeysEnabled();\nif (!getGeneratedKeys && usesIdentityGeneration(metadata)) {\n    throw new IllegalStateException(\"Spanner cannot SELECT the last identity value - enable getGeneratedKeys or assign ids client-side\");\n}","typeGuard":null,"tryCatchPattern":"try {\n    session.persist(person);\n    session.flush();\n}\ncatch (MappingException e) {\n    if (e.getMessage().contains(\"does not support selecting the last generated identity value\")) {\n        throw new UnsupportedOperationException(\"Assign ids client-side (UUID) on Spanner\", e);\n    }\n    throw e;\n}","preventionTips":["Never disable hibernate.jdbc.use_get_generated_keys on Spanner with identity mappings","Prefer client-assigned keys (UUID/string) on Spanner to sidestep generated-key retrieval entirely","Smoke-test one insert of every identity entity type in CI for each target database"],"tags":["hibernate","spanner","identity","generated-keys","mapping"],"backgroundTag":"identity-generation-unsupported","analyzedSha":"fad1729dce015f908198d57a8d80274a30f905a5","analyzedAt":"2026-08-22T04:13:57.527Z","schemaVersion":2},"datasetVersion":"2026-08-22T09:17:25.309Z"}