{"record":{"id":"b8b52563af5c1033","repo":"hibernate/hibernate-orm","slug":"the-database-returned-no-natively-generated-values","errorCode":null,"errorMessage":"The database returned no natively generated values : {}","messagePattern":"The database returned no natively generated values : (.+?)","errorType":"exception","errorClass":"HibernateException","httpStatus":null,"severity":"error","filePath":"hibernate-core/src/main/java/org/hibernate/generator/values/internal/GeneratedValuesHelper.java","lineNumber":174,"sourceCode":"\t\t\t\tmappingProducer.resolve( directResultSetAccess, influencers, factory ),\n\t\t\t\tnull,\n\t\t\t\texecutionContext\n\t\t);\n\t\tfinal var valuesProcessingState =\n\t\t\t\tnew JdbcValuesSourceProcessingStateStandardImpl( executionContext, NO_OPTIONS );\n\t\tfinal RowReader<Object[]> rowReader = ResultsHelper.createRowReader(\n\t\t\t\tfactory,\n\t\t\t\tRowTransformerArrayImpl.instance(),\n\t\t\t\tObject[].class,\n\t\t\t\tjdbcValues\n\t\t);\n\t\tfinal var rowProcessingState =\n\t\t\t\tnew RowProcessingStateStandardImpl( valuesProcessingState, executionContext, rowReader, jdbcValues );\n\t\tfinal List<Object[]> results =\n\t\t\t\tListResultsConsumer.<Object[]>instance( ListResultsConsumer.UniqueSemantic.NONE )\n\t\t\t\t\t\t.consume( jdbcValues, session, NO_OPTIONS, valuesProcessingState, rowProcessingState, rowReader );\n\t\tif ( results.isEmpty() ) {\n\t\t\tthrow new HibernateException( \"The database returned no natively generated values : \"\n\t\t\t\t\t\t\t\t\t\t\t+ persister.getNavigableRole().getFullPath() );\n\t\t}\n\t\treturn results.get( 0 );\n\t}\n\n\t/**\n\t * Utility method that instantiates a {@link JdbcValuesMappingProducer} so it can be cached by the\n\t * {@link GeneratedValuesMutationDelegate delegates} when they are instantiated.\n\t *\n\t * @param persister the current entity persister\n\t * @param timing the timing of the mutation operation\n\t * @param supportsArbitraryValues if we should process arbitrary (non-identifier) generated values\n\t * @param supportsRowId if we should process {@link org.hibernate.metamodel.mapping.EntityRowIdMapping rowid}s\n\t * {@code false} if we should retrieve the index through the column expression\n\t *\n\t * @return the instantiated jdbc values mapping producer\n\t */\n\tpublic static GeneratedValuesMappingProducer createMappingProducer(","sourceCodeStart":156,"sourceCodeEnd":192,"githubUrl":"https://github.com/hibernate/hibernate-orm/blob/fad1729dce015f908198d57a8d80274a30f905a5/hibernate-core/src/main/java/org/hibernate/generator/values/internal/GeneratedValuesHelper.java#L156-L192","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Switch the identifier from IDENTITY to SEQUENCE (+ allocationSize) so ids are fetched before insert and no getGeneratedKeys/RETURNING roundtrip is needed","If the table has a trigger, fix it so the generated columns are still returned (SQL Server: avoid result-set-eating trigger patterns)","Upgrade the JDBC driver to a version known to return generated keys correctly (mssql-jdbc over jTDS, current Jaybird, current ojdbc)","For view/INSTEAD OF trigger mappings, remove database-side generation annotations and read values explicitly after flush","Verify the configured dialect matches your database version"],"exampleFix":"// before — identity + trigger on SQL Server returns no generated-keys row\n@Id @GeneratedValue(strategy = GenerationType.IDENTITY)\nLong id;\n\n// after — sequence: id fetched before insert, no readback dependency\n@Id @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = \"order_seq\")\n@SequenceGenerator(name = \"order_seq\", sequenceName = \"order_seq\", allocationSize = 50)\nLong id;","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try {\n    session.persist(order);\n    session.flush();\n}\ncatch (HibernateException e) {\n    if (e.getMessage() != null\n            && e.getMessage().startsWith(\"The database returned no natively generated values\")) {\n        // the row may exist without a returned id: do NOT blind-retry the insert;\n        // re-query by natural/unique key, or roll back and switch to sequence-based ids\n        throw new GeneratedKeysUnavailableException(order, e);\n    }\n    throw e;\n}","preventionTips":["Prefer SEQUENCE over IDENTITY where the dialect supports it","Audit any trigger added to tables used with identity or generated columns","Pin recent JDBC drivers and run insert-readback tests in CI against the real database","Avoid @GeneratedColumn on views with INSTEAD OF triggers"],"tags":["hibernate","generated-keys","jdbc","identity","returning-clause","triggers"],"backgroundTag":"no-generated-keys-returned","analyzedSha":"fad1729dce015f908198d57a8d80274a30f905a5","analyzedAt":"2026-08-22T04:13:57.527Z","schemaVersion":2},"datasetVersion":"2026-08-22T09:17:25.309Z"}