single_table inheritancetype discriminatorcolumn java hibernate inheritance jpa single-table-inheritance

java - inheritancetype - Cómo obtener DiscriminatorValue en tiempo de ejecución



@discriminatorcolumn (5)

Estamos llamando a un método que toma un ApplicationProcess como parámetro, y quiero evitar usar instanceof para verificar de qué tipo es. Sería más genial si pudiera hacer algo como (...)

No creo que sea más genial, esto parece peor que llamarme instanceOf : si por alguna razón cambias el valor del discriminador, rompería tu código.

Si necesita verificar el tipo, use instanceOf . Un truco usando el discriminador no va a hacer las cosas más agradables, solo haría que tu código sea menos robusto.

Tenemos las siguientes clases

@Entity @Inheritance(strategy = InheritanceType.SINGLE_TABLE) // optional annotation as this is default @DiscriminatorColumn(name = "apType", discriminatorType = DiscriminatorType.STRING, length = 255) @DiscriminatorValue("AP") public class ApplicationProcess { }

Y esto

@Entity @DiscriminatorValue("APS") public class ApplicationProcessScheme extends ApplicationProcess { }

Ahora necesito saber en tiempo de ejecución si el ApplicationProcess es DiscriminatorValue AP or APS . Como esto se maneja automáticamente por jpa, no tengo forma de obtener este valor.

Estamos llamando a un método que toma un ApplicationProcess como parámetro, y quiero evitar usar instanceof para verificar de qué tipo es. Sería más genial si pudiera hacer algo como

applicationProcess.getApType().equals("AP");


He utilizado la siguiente solución para obtener este valor en tiempo de ejecución, suponiendo que no sabe de antemano cuál es el tipo de herencia:

SessionFactoryImpl sessionFactory = entityManager.getEntityManagerFactory().unwrap(SessionFactoryImpl.class); EntityPersister entityPersister = sessionFactory.getEntityPersister( Task.class.getPackage().getName()+"."+param.getValue().get(0) ); int clazz_ = 0; if(UnionSubclassEntityPersister.class.isInstance(entityPersister)) { clazz_ = (Integer) ((UnionSubclassEntityPersister) entityPersister).getDiscriminatorValue(); } else if(JoinedSubclassEntityPersister.class.isInstance(entityPersister)) { clazz_ = (Integer) ((JoinedSubclassEntityPersister) entityPersister).getDiscriminatorValue(); }

Debe cambiar el tipo de clazz_ acuerdo con sus anotaciones discriminatorType (Integer es el valor predeterminado para las estrategias de unión y unión). Esta solución también se puede usar para SINGLE_TABLE , si agrega tal caso; o puede usar las otras soluciones mencionadas aquí.


Puede asignar su discriminador como una propiedad de solo lectura:

public class ApplicationProcess { ... @Column(name = "apType", insertable = false, updatable = false) private String apType; }


Puede usar Anotación de Fórmula. Si está utilizando Hibernate, puede usar el siguiente código según este enlace :

private String theApType; @Formula("apType") String getTheApType() { return theApType; }

Por supuesto, usted podría usarlo en sus consultas.


Puedo imaginar algunos casos en los que podría ser útil, pero a pesar de la razón por la que necesita esto, puede crear en su método de clase abstracta como

@Transient public String getDiscriminatorValue(){ DiscriminatorValue val = this.getClass().getAnnotation( DiscriminatorValue.class ); return val == null ? null : val.value(); }