with tutorial the same español different associated already hibernate jpa polymorphism criteria detachedcriteria

hibernate - tutorial - Recuperar objetos de hibernación polimórficos utilizando una consulta de criterios



a different object with the same identifier value was already associated with the session (2)

En mi modelo, tengo una clase abstracta de "Usuario" y múltiples subclases como Solicitante, HiringManager y Entrevistador. Están en una sola mesa, y tengo un solo DAO para administrarlos todos.

Usuario:

@Entity @Table(name="User") @Inheritance(strategy=InheritanceType.SINGLE_TABLE) @DiscriminatorColumn( name="role", discriminatorType=DiscriminatorType.STRING ) public abstract class User extends BaseObject implements Identifiable<Long> ...

HiringManager (por ejemplo):

@Entity @DiscriminatorValue("HIRING_MANAGER") public class HiringManager extends User ...

Ahora bien, si quisiera, por ejemplo, obtener todos los gerentes de contratación que no están asociados con un departamento, ¿cómo podría hacerlo? Me imagino que se vería algo así como:

DetachedCriteria c = DetachedCriteria.forClass(User.class); c.add(Restrictions.eq("role", "HIRING_MANAGER")); c.add(Restrictions.isNull("department")); List<User> results = getHibernateTemplate().findByCriteria(c);

Pero cuando ejecuto esto, Hibernate se queja "could not resolve property: role" (que en realidad tiene sentido porque la clase User realmente no tiene una propiedad de rol explícita)
Entonces, ¿cuál es la forma correcta de hacer lo que estoy tratando de hacer?


Puede que me esté perdiendo algo obvio, pero dado que desea encontrar gerentes de contratación, ¿por qué no pasa la subclase HiringManager como clase a Criteria ?

Por si acaso, existe una propiedad de class especial que puede usar para restringir una consulta a un subtipo. De la documentación de referencia de Hibernate:

14.9. La cláusula where

...

La class propiedad especial accede al valor discriminador de una instancia en el caso de persistencia polimórfica. Un nombre de clase Java incrustado en la cláusula where se traducirá a su valor discriminador.

from Cat cat where cat.class = DomesticCat

También puede usar esta propiedad de clase especial con la API Criteria, pero con un cambio menor: debe usar el valor discriminador como valor.

c.add(Restrictions.eq("class", "HIRING_MANAGER"));

A diferencia de HQL, parece que Hibernate no está haciendo la traducción con la API de Criteria. Realmente no me gusta la idea de usar el valor del discriminador en el código y quizás haya otra forma más limpia, pero no me consta. Pero funciona.


Tenga en cuenta que esto también funciona para las asignaciones de herencia de Subclase unida, con una advertencia. La clase utilizada en la Restricción debe ser una clase concreta. Si tiene un modelo como Animal <- Mamífero <- Gato, no puede hacer Restrictions.eq("class", Mammal.class); y esperan recuperar todos los Mamíferos. En lugar de eso, tuve que usar la fuerza bruta usando Restrictions.or con todas las clases concretas conocidas (el uso de Restrictions.in () dio una excepción de lanzamiento de clase al ejecutar la consulta).