diff --git a/hibernate-core/src/main/java/org/hibernate/annotations/DiscriminatorFormula.java b/hibernate-core/src/main/java/org/hibernate/annotations/DiscriminatorFormula.java index a6301df28a..d3014d6323 100644 --- a/hibernate-core/src/main/java/org/hibernate/annotations/DiscriminatorFormula.java +++ b/hibernate-core/src/main/java/org/hibernate/annotations/DiscriminatorFormula.java @@ -6,9 +6,12 @@ */ package org.hibernate.annotations; +import jakarta.persistence.DiscriminatorType; + import java.lang.annotation.Retention; import java.lang.annotation.Target; +import static jakarta.persistence.DiscriminatorType.STRING; import static java.lang.annotation.ElementType.TYPE; import static java.lang.annotation.RetentionPolicy.RUNTIME; @@ -18,6 +21,40 @@ * the hierarchy. *
* Used in place of the JPA {@link jakarta.persistence.DiscriminatorColumn}. + *
+ * For example, we might declare a supertype as follows: + *
{@code + * @Entity + * @DiscriminatorFormula(discriminatorType = INTEGER, + * value = "case when value1 is not null then 1 when value2 is not null then 2 end") + * public abstract class AbstractChild { + * @Id + * @GeneratedValue + * Integer id; + * ... + * } + * }+ * and then each concrete subclass must specify a matching discriminator value: + *
{@code + * @Entity + * @DiscriminatorValue("1") + * public class ConcreteChild1 extends AbstractChild { + * @Basic(optional = false) + * @Column(name = "VALUE1") + * String value; + * ... + * } + * }+ *
{@code + * @Entity + * @DiscriminatorValue("2") + * public class ConcreteChild2 extends AbstractChild { + * @Basic(optional = false) + * @Column(name = "VALUE2") + * String value; + * ... + * } + * }* * @see Formula * @see DialectOverride.DiscriminatorFormula @@ -25,11 +62,19 @@ * @author Emmanuel Bernard * @author Steve Ebersole */ -@Target({TYPE}) +@Target(TYPE) @Retention(RUNTIME) public @interface DiscriminatorFormula { /** * The formula string. */ String value(); + + /** + * The type of value returned by the formula. + *
+ * This is required, unless the {@linkplain #value()
+ * expression} is of type {@code varchar} or similar.
+ */
+ DiscriminatorType discriminatorType() default STRING;
}
diff --git a/hibernate-core/src/main/java/org/hibernate/boot/model/internal/AnnotatedDiscriminatorColumn.java b/hibernate-core/src/main/java/org/hibernate/boot/model/internal/AnnotatedDiscriminatorColumn.java
index 49d5d83019..dc81b873bd 100644
--- a/hibernate-core/src/main/java/org/hibernate/boot/model/internal/AnnotatedDiscriminatorColumn.java
+++ b/hibernate-core/src/main/java/org/hibernate/boot/model/internal/AnnotatedDiscriminatorColumn.java
@@ -43,18 +43,26 @@ public void setDiscriminatorTypeName(String discriminatorTypeName) {
}
public static AnnotatedDiscriminatorColumn buildDiscriminatorColumn(
- DiscriminatorType type,
DiscriminatorColumn discriminatorColumn,
DiscriminatorFormula discriminatorFormula,
MetadataBuildingContext context) {
final AnnotatedColumns parent = new AnnotatedColumns();
parent.setBuildingContext( context );
final AnnotatedDiscriminatorColumn column = new AnnotatedDiscriminatorColumn();
+ final DiscriminatorType discriminatorType;
if ( discriminatorFormula != null ) {
+ final DiscriminatorType type = discriminatorFormula.discriminatorType();
+ if ( type == DiscriminatorType.STRING ) {
+ discriminatorType = discriminatorColumn == null ? type : discriminatorColumn.discriminatorType();
+ }
+ else {
+ discriminatorType = type;
+ }
column.setImplicit( false );
column.setFormula( discriminatorFormula.value() );
}
else if ( discriminatorColumn != null ) {
+ discriminatorType = discriminatorColumn.discriminatorType();
column.setImplicit( false );
if ( !discriminatorColumn.columnDefinition().isEmpty() ) {
column.setSqlType( discriminatorColumn.columnDefinition() );
@@ -65,9 +73,10 @@ else if ( discriminatorColumn != null ) {
column.setNullable( false );
}
else {
+ discriminatorType = DiscriminatorType.STRING;
column.setImplicit( true );
}
- setDiscriminatorType( type, discriminatorColumn, column );
+ setDiscriminatorType( discriminatorType, discriminatorColumn, column );
column.setParent( parent );
column.bind();
return column;
diff --git a/hibernate-core/src/main/java/org/hibernate/boot/model/internal/EntityBinder.java b/hibernate-core/src/main/java/org/hibernate/boot/model/internal/EntityBinder.java
index 7a2c9e565d..281f75b0bd 100644
--- a/hibernate-core/src/main/java/org/hibernate/boot/model/internal/EntityBinder.java
+++ b/hibernate-core/src/main/java/org/hibernate/boot/model/internal/EntityBinder.java
@@ -779,16 +779,13 @@ private void processDiscriminatorOptions() {
private AnnotatedDiscriminatorColumn processSingleTableDiscriminatorProperties(InheritanceState inheritanceState) {
final DiscriminatorColumn discriminatorColumn = annotatedClass.getAnnotation( DiscriminatorColumn.class );
- final DiscriminatorType discriminatorType = discriminatorColumn != null
- ? discriminatorColumn.discriminatorType()
- : DiscriminatorType.STRING;
final DiscriminatorFormula discriminatorFormula =
getOverridableAnnotation( annotatedClass, DiscriminatorFormula.class, context );
final boolean isRoot = !inheritanceState.hasParents();
final AnnotatedDiscriminatorColumn discriminator = isRoot
- ? buildDiscriminatorColumn( discriminatorType, discriminatorColumn, discriminatorFormula, context )
+ ? buildDiscriminatorColumn( discriminatorColumn, discriminatorFormula, context )
: null;
if ( discriminatorColumn != null && !isRoot ) {
//TODO: shouldn't this be an error?!
@@ -835,10 +832,7 @@ private AnnotatedDiscriminatorColumn processJoinedDiscriminatorProperties(Inheri
}
if ( generateDiscriminatorColumn ) {
- final DiscriminatorType discriminatorType = discriminatorColumn != null
- ? discriminatorColumn.discriminatorType()
- : DiscriminatorType.STRING;
- return buildDiscriminatorColumn( discriminatorType, discriminatorColumn, null, context );
+ return buildDiscriminatorColumn( discriminatorColumn, null, context );
}
}
else {
diff --git a/hibernate-core/src/test/java/org/hibernate/orm/test/annotations/sharedfk/AbstractChild.java b/hibernate-core/src/test/java/org/hibernate/orm/test/annotations/sharedfk/AbstractChild.java
index 6df8f858b9..a8740541c4 100644
--- a/hibernate-core/src/test/java/org/hibernate/orm/test/annotations/sharedfk/AbstractChild.java
+++ b/hibernate-core/src/test/java/org/hibernate/orm/test/annotations/sharedfk/AbstractChild.java
@@ -3,13 +3,14 @@
import jakarta.persistence.*;
import org.hibernate.annotations.DiscriminatorFormula;
+import static jakarta.persistence.DiscriminatorType.INTEGER;
+
@Entity
@Table(name = " INHERITANCE_TAB")
-@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
-@Access(AccessType.FIELD)
//@DiscriminatorColumn(name = "DISC")
-@DiscriminatorFormula("case when value1 is not null then 1 when value2 is not null then 2 end")
-public class AbstractChild {
+@DiscriminatorFormula(discriminatorType = INTEGER,
+ value = "case when value1 is not null then 1 when value2 is not null then 2 end")
+public abstract class AbstractChild {
@Id
@GeneratedValue
@Column(name = "ID")
diff --git a/hibernate-core/src/test/java/org/hibernate/orm/test/annotations/sharedfk/ConcreteChild1.java b/hibernate-core/src/test/java/org/hibernate/orm/test/annotations/sharedfk/ConcreteChild1.java
index 2885e0492f..786bb24dff 100644
--- a/hibernate-core/src/test/java/org/hibernate/orm/test/annotations/sharedfk/ConcreteChild1.java
+++ b/hibernate-core/src/test/java/org/hibernate/orm/test/annotations/sharedfk/ConcreteChild1.java
@@ -8,7 +8,6 @@
import jakarta.persistence.Entity;
@Entity
-@Access(AccessType.FIELD)
@DiscriminatorValue("1")
public class ConcreteChild1 extends AbstractChild {
@Basic(optional = false)
diff --git a/hibernate-core/src/test/java/org/hibernate/orm/test/annotations/sharedfk/ConcreteChild2.java b/hibernate-core/src/test/java/org/hibernate/orm/test/annotations/sharedfk/ConcreteChild2.java
index d505edc5ec..0a83996076 100644
--- a/hibernate-core/src/test/java/org/hibernate/orm/test/annotations/sharedfk/ConcreteChild2.java
+++ b/hibernate-core/src/test/java/org/hibernate/orm/test/annotations/sharedfk/ConcreteChild2.java
@@ -3,7 +3,6 @@
import jakarta.persistence.*;
@Entity
-@Access(AccessType.FIELD)
@DiscriminatorValue("2")
public class ConcreteChild2 extends AbstractChild {
@Basic(optional = false)
diff --git a/hibernate-core/src/test/java/org/hibernate/orm/test/annotations/sharedfk/Parent.java b/hibernate-core/src/test/java/org/hibernate/orm/test/annotations/sharedfk/Parent.java
index 45072435b8..2021d910c4 100644
--- a/hibernate-core/src/test/java/org/hibernate/orm/test/annotations/sharedfk/Parent.java
+++ b/hibernate-core/src/test/java/org/hibernate/orm/test/annotations/sharedfk/Parent.java
@@ -19,8 +19,8 @@ public class Parent {
@OneToMany( fetch= FetchType.EAGER)
@JoinColumn(name = "PARENT_ID")
@OrderColumn(name = "ORDER_C")
-
List