{"record":{"id":"f9bf7777f8edcaaa","repo":"hibernate/hibernate-orm","slug":"discriminator-formulas-on-joined-inheritance-hiera","errorCode":null,"errorMessage":"Discriminator formulas on joined inheritance hierarchies not supported at this time","messagePattern":"Discriminator formulas on joined inheritance hierarchies not supported at this time","errorType":"exception","errorClass":"MappingException","httpStatus":null,"severity":"error","filePath":"hibernate-core/src/main/java/org/hibernate/persister/entity/JoinedSubclassEntityPersister.java","lineNumber":186,"sourceCode":"\n\t\tfinal var dialect = creationContext.getDialect();\n\t\tfinal var typeConfiguration = creationContext.getTypeConfiguration();\n\t\tfinal var basicTypeRegistry = typeConfiguration.getBasicTypeRegistry();\n\n\t\t// DISCRIMINATOR\n\n\t\tif ( persistentClass.isPolymorphic() ) {\n\t\t\tforceDiscriminator = persistentClass.isForceDiscriminator();\n\t\t\tfinal var discriminatorMapping = persistentClass.getDiscriminator();\n\t\t\tif ( discriminatorMapping != null ) {\n\t\t\t\tLOG.tracef( \"Encountered explicit discriminator mapping for joined inheritance\" );\n\t\t\t\tfinal var selectable = discriminatorMapping.getSelectables().get(0);\n\t\t\t\tif ( selectable instanceof Column column ) {\n\t\t\t\t\texplicitDiscriminatorColumnName = column.getQuotedName( dialect );\n\t\t\t\t\tdiscriminatorAlias = column.getAlias( dialect, persistentClass.getRootTable() );\n\t\t\t\t}\n\t\t\t\telse {\n\t\t\t\t\tthrow new MappingException( \"Discriminator formulas on joined inheritance hierarchies not supported at this time\" );\n\t\t\t\t}\n\t\t\t\tdiscriminatorType = DiscriminatorHelper.getDiscriminatorType( persistentClass );\n\t\t\t\tdiscriminatorValue = DiscriminatorHelper.getDiscriminatorValue( persistentClass );\n\t\t\t\tdiscriminatorSQLString = DiscriminatorHelper.getDiscriminatorSQLValue( persistentClass, dialect );\n\t\t\t}\n\t\t\telse {\n\t\t\t\texplicitDiscriminatorColumnName = null;\n\t\t\t\tdiscriminatorAlias = IMPLICIT_DISCRIMINATOR_ALIAS;\n\t\t\t\tdiscriminatorType = basicTypeRegistry.resolve( StandardBasicTypes.INTEGER );\n\t\t\t\ttry {\n\t\t\t\t\tdiscriminatorValue = new DiscriminatorValue.Literal( persistentClass.getSubclassId() );\n\t\t\t\t\tdiscriminatorSQLString = Integer.toString( persistentClass.getSubclassId() );\n\t\t\t\t}\n\t\t\t\tcatch ( Exception e ) {\n\t\t\t\t\tthrow new MappingException( \"Could not format discriminator value to SQL string\", e );\n\t\t\t\t}\n\t\t\t}\n\t\t}","sourceCodeStart":168,"sourceCodeEnd":204,"githubUrl":"https://github.com/hibernate/hibernate-orm/blob/fad1729dce015f908198d57a8d80274a30f905a5/hibernate-core/src/main/java/org/hibernate/persister/entity/JoinedSubclassEntityPersister.java#L168-L204","documentation":"When a polymorphic JOINED hierarchy declares an explicit discriminator mapping, JoinedSubclassEntityPersister inspects its first selectable and accepts only a real Column; anything else — a formula (@DiscriminatorFormula or XML <discriminator formula=\"...\">) — fails boot with MappingException('Discriminator formulas on joined inheritance hierarchies not supported at this time'). Formulas work in SINGLE_TABLE hierarchies but not in JOINED ones.","triggerScenarios":"@Inheritance(strategy = JOINED) on the root combined with @DiscriminatorFormula (or an XML discriminator formula) while the hierarchy declares an explicit discriminator mapping; polymorphic joined hierarchies whose discriminator is a computed SQL expression (CASE, view column).","commonSituations":"Deriving the discriminator from a computed column or expression; migrating a SINGLE_TABLE hierarchy that used a formula to JOINED; DBA mandates that the type marker be an expression rather than a stored column.","solutions":["Replace @DiscriminatorFormula with a real @DiscriminatorColumn on the joined hierarchy","Remove the explicit discriminator mapping entirely — JOINED hierarchies work with Hibernate's implicit integer subclass ids","If the formula is a hard requirement, keep SINGLE_TABLE inheritance where discriminator formulas are supported"],"exampleFix":"// before\n@Entity\n@Inheritance(strategy = InheritanceType.JOINED)\n@DiscriminatorFormula(\"case when type_code is null then 'P' else 'C' end\")\npublic abstract class Billing { ... }\n\n// after\n@Entity\n@Inheritance(strategy = InheritanceType.JOINED)\n@DiscriminatorColumn(name = \"billing_type\", discriminatorType = STRING)\npublic abstract class Billing { ... }","handlingStrategy":"validation","validationCode":"Inheritance inh = root.getAnnotation(Inheritance.class);\nif ( root.isAnnotationPresent(DiscriminatorFormula.class) && inh != null\n        && inh.strategy() == InheritanceType.JOINED ) {\n    throw new IllegalStateException(\n        root.getName() + \": @DiscriminatorFormula is not supported with JOINED inheritance\");\n}","typeGuard":null,"tryCatchPattern":"try {\n    SessionFactory sf = metadata.getSessionFactoryBuilder().build();\n}\ncatch ( org.hibernate.MappingException e ) {\n    throw new IllegalStateException(\"SessionFactory boot failed: \" + e.getMessage(), e);\n}","preventionTips":["When switching inheritance strategies, re-validate all discriminator annotations on the root","Reserve @DiscriminatorFormula for SINGLE_TABLE hierarchies","Add a boot test per inheritance hierarchy configuration"],"tags":["hibernate","orm","discriminator","inheritance","joined-inheritance","mapping"],"backgroundTag":"discriminator-formula-unsupported","analyzedSha":"fad1729dce015f908198d57a8d80274a30f905a5","analyzedAt":"2026-08-22T04:13:57.527Z","schemaVersion":2},"datasetVersion":"2026-08-22T09:17:25.309Z"}