{"record":{"id":"a8b34a6bd913a4de","repo":"hibernate/hibernate-orm","slug":"unsupported-generated-modelpart","errorCode":null,"errorMessage":"Unsupported generated ModelPart: {}","messagePattern":"Unsupported generated ModelPart: (.+?)","errorType":"exception","errorClass":"UnsupportedOperationException","httpStatus":null,"severity":"error","filePath":"hibernate-core/src/main/java/org/hibernate/generator/values/internal/GeneratedValuesHelper.java","lineNumber":232,"sourceCode":"\t\tfinal var mappingProducer = new GeneratedValuesMappingProducer();\n\t\tfor ( int i = 0; i < generatedProperties.size(); i++ ) {\n\t\t\tfinal var modelPart = generatedProperties.get( i );\n\t\t\tfinal var basicModelPart = modelPart.asBasicValuedModelPart();\n\t\t\tif ( basicModelPart != null ) {\n\t\t\t\tmappingProducer.addResultBuilder( new GeneratedValueBasicResultBuilder(\n\t\t\t\t\t\tparentNavigablePath.append( basicModelPart.getSelectableName() ),\n\t\t\t\t\t\tbasicModelPart,\n\t\t\t\t\t\ttableGroup,\n\t\t\t\t\t\t// For composite identifiers we may expand generated identifier parts even when\n\t\t\t\t\t\t// supportsArbitraryValues is false; in that case, rely on positional ordering\n\t\t\t\t\t\t// instead of column name resolution.\n\t\t\t\t\t\tsupportsArbitraryValues || !basicModelPart.isEntityIdentifierMapping()\n\t\t\t\t\t\t\t\t? i\n\t\t\t\t\t\t\t\t: null\n\t\t\t\t) );\n\t\t\t}\n\t\t\telse {\n\t\t\t\tthrow new UnsupportedOperationException( \"Unsupported generated ModelPart: \" + modelPart.getPartName() );\n\t\t\t}\n\t\t}\n\t\treturn mappingProducer;\n\t}\n\n\tpublic static BasicValuedModelPart getActualGeneratedModelPart(BasicValuedModelPart modelPart) {\n\t\t// Use the root entity descriptor's identifier mapping to get the correct selection\n\t\t// expression since we always retrieve generated values for the root table only\n\t\treturn modelPart.isEntityIdentifierMapping()\n\t\t\t\t? modelPart.findContainingEntityMapping()\n\t\t\t\t\t\t.getRootEntityDescriptor()\n\t\t\t\t\t\t.getIdentifierMapping()\n\t\t\t\t\t\t.asBasicValuedModelPart()\n\t\t\t\t: modelPart;\n\t}\n\n\t/**\n\t * Returns a list of {@link ModelPart}s that represent the actual generated values","sourceCodeStart":214,"sourceCodeEnd":250,"githubUrl":"https://github.com/hibernate/hibernate-orm/blob/fad1729dce015f908198d57a8d80274a30f905a5/hibernate-core/src/main/java/org/hibernate/generator/values/internal/GeneratedValuesHelper.java#L214-L250","documentation":"When Hibernate builds the cached JDBC result mapping used to read database-generated values back after insert/update, every generated part must resolve to a basic (single-column) model part (asBasicValuedModelPart() != null). If a generated selectable is a non-basic ModelPart — for example an embeddable attribute whose members are DB-generated — this UnsupportedOperationException is thrown while constructing the mapping producer.","triggerScenarios":"Database-side generation attached to a non-identifier embeddable: @GeneratedColumn or identity generation on members of an @Embedded (non-id) attribute, so the generated-properties list contains an EmbeddableValuedModelPart that the result-mapping builder cannot expand (only composite identifiers get expanded).","commonSituations":"Marking embeddable members as DB-generated on databases whose dialect reads values back via RETURNING; custom generators declaring event types on embeddables; usually reveals a Hibernate limitation rather than a plain configuration mistake.","solutions":["Move database-side generation (@GeneratedColumn, identity) to basic single-column attributes of the entity itself","Use in-memory generation for embeddable members (@Generated or a BeforeExecutionGenerator) so values are written as parameters and no readback is needed","If the embeddable must stay DB-generated, split the generated member out of the embeddable onto the entity","If the mapping looks like it should work, search/raise a Hibernate JIRA — 'Unsupported generated ModelPart' is an internal guard, often a limitation"],"exampleFix":"// before — DB-generated member inside a non-id embeddable needs embeddable readback\n@Embedded\nAudit audit;\n\n@Embeddable class Audit {\n    @GeneratedColumn(event = EventType.INSERT)   // embeddable part lands in generated readback\n    Instant createdAt;\n}\n\n// after — generate in memory; written as a plain parameter\n@Embeddable class Audit {\n    @Generated(event = EventType.INSERT)\n    Instant createdAt;\n}","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try {\n    sessionFactory = metadata.buildSessionFactory();\n}\ncatch (UnsupportedOperationException e) {\n    if (e.getMessage() != null && e.getMessage().startsWith(\"Unsupported generated ModelPart\")) {\n        throw new IllegalStateException(\n                \"A non-basic attribute is marked database-generated; move @GeneratedColumn to \"\n                + \"single-column attributes or use @Generated: \" + e.getMessage(), e);\n    }\n    throw e;\n}","preventionTips":["Reserve @GeneratedColumn and identity generation for basic attributes; use @Generated for embeddable members","Test every generated-annotation combination in a bootstrap CI test","Search Hibernate JIRA when hitting internal UnsupportedOperationExceptions — they usually mark mapping limitations"],"tags":["hibernate","generated-values","embeddable","mapping","internal"],"backgroundTag":"unsupported-mapping-construct","analyzedSha":"fad1729dce015f908198d57a8d80274a30f905a5","analyzedAt":"2026-08-22T04:13:57.527Z","schemaVersion":2},"datasetVersion":"2026-08-22T09:17:25.309Z"}