HHH-15935 add discriminatorType to @DiscriminatorFormula
This commit is contained in:
parent
a4191c9e11
commit
491b1bc06f
|
@ -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 @@ import static java.lang.annotation.RetentionPolicy.RUNTIME;
|
|||
* the hierarchy.
|
||||
* <p>
|
||||
* Used in place of the JPA {@link jakarta.persistence.DiscriminatorColumn}.
|
||||
* <p>
|
||||
* For example, we might declare a supertype as follows:
|
||||
* <pre>{@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;
|
||||
* ...
|
||||
* }
|
||||
* }</pre>
|
||||
* and then each concrete subclass must specify a matching discriminator value:
|
||||
* <pre>{@code
|
||||
* @Entity
|
||||
* @DiscriminatorValue("1")
|
||||
* public class ConcreteChild1 extends AbstractChild {
|
||||
* @Basic(optional = false)
|
||||
* @Column(name = "VALUE1")
|
||||
* String value;
|
||||
* ...
|
||||
* }
|
||||
* }</pre>
|
||||
* <pre>{@code
|
||||
* @Entity
|
||||
* @DiscriminatorValue("2")
|
||||
* public class ConcreteChild2 extends AbstractChild {
|
||||
* @Basic(optional = false)
|
||||
* @Column(name = "VALUE2")
|
||||
* String value;
|
||||
* ...
|
||||
* }
|
||||
* }</pre>
|
||||
*
|
||||
* @see Formula
|
||||
* @see DialectOverride.DiscriminatorFormula
|
||||
|
@ -25,11 +62,19 @@ import static java.lang.annotation.RetentionPolicy.RUNTIME;
|
|||
* @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.
|
||||
* <p>
|
||||
* This is required, unless the {@linkplain #value()
|
||||
* expression} is of type {@code varchar} or similar.
|
||||
*/
|
||||
DiscriminatorType discriminatorType() default STRING;
|
||||
}
|
||||
|
|
|
@ -43,18 +43,26 @@ public class AnnotatedDiscriminatorColumn extends AnnotatedColumn {
|
|||
}
|
||||
|
||||
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 @@ public class AnnotatedDiscriminatorColumn extends AnnotatedColumn {
|
|||
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;
|
||||
|
|
|
@ -779,16 +779,13 @@ public class EntityBinder {
|
|||
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 @@ public class EntityBinder {
|
|||
}
|
||||
|
||||
if ( generateDiscriminatorColumn ) {
|
||||
final DiscriminatorType discriminatorType = discriminatorColumn != null
|
||||
? discriminatorColumn.discriminatorType()
|
||||
: DiscriminatorType.STRING;
|
||||
return buildDiscriminatorColumn( discriminatorType, discriminatorColumn, null, context );
|
||||
return buildDiscriminatorColumn( discriminatorColumn, null, context );
|
||||
}
|
||||
}
|
||||
else {
|
||||
|
|
|
@ -3,13 +3,14 @@ package org.hibernate.orm.test.annotations.sharedfk;
|
|||
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")
|
||||
|
|
|
@ -8,7 +8,6 @@ import jakarta.persistence.DiscriminatorValue;
|
|||
import jakarta.persistence.Entity;
|
||||
|
||||
@Entity
|
||||
@Access(AccessType.FIELD)
|
||||
@DiscriminatorValue("1")
|
||||
public class ConcreteChild1 extends AbstractChild {
|
||||
@Basic(optional = false)
|
||||
|
|
|
@ -3,7 +3,6 @@ package org.hibernate.orm.test.annotations.sharedfk;
|
|||
import jakarta.persistence.*;
|
||||
|
||||
@Entity
|
||||
@Access(AccessType.FIELD)
|
||||
@DiscriminatorValue("2")
|
||||
public class ConcreteChild2 extends AbstractChild {
|
||||
@Basic(optional = false)
|
||||
|
|
|
@ -19,8 +19,8 @@ public class Parent {
|
|||
@OneToMany( fetch= FetchType.EAGER)
|
||||
@JoinColumn(name = "PARENT_ID")
|
||||
@OrderColumn(name = "ORDER_C")
|
||||
|
||||
List<ConcreteChild1> child1s = new LinkedList<>();
|
||||
|
||||
@OneToMany( fetch= FetchType.EAGER)
|
||||
@JoinColumn(name = "PARENT_ID")
|
||||
@OrderColumn(name = "ORDER_C")
|
||||
|
|
Loading…
Reference in New Issue