В моей модели у меня есть "Пользовательский" класс краткого обзора и несколько подклассов, таких как Заявитель, HiringManager и Интервьюер. Они находятся в единственной таблице, и у меня есть единственный ДАО для управления ими всеми.
Пользователь:
@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 (например):
@Entity
@DiscriminatorValue("HIRING_MANAGER")
public class HiringManager extends User ...
Теперь, если я хотел, скажем, получить всех менеджеров по найму, которые не связаны с отделом, как я сделал бы это? Я предполагаю, что это посмотрело бы что-то как:
DetachedCriteria c = DetachedCriteria.forClass(User.class);
c.add(Restrictions.eq("role", "HIRING_MANAGER"));
c.add(Restrictions.isNull("department"));
List<User> results = getHibernateTemplate().findByCriteria(c);
Но то, когда я выполняю это, В спящем режиме, жалуется, "не мог разрешить свойство: роль" (Который на самом деле имеет смысл, потому что Пользовательский класс действительно не имеет явного ролевого свойства),
Таким образом, что правильный путь состоит в том, чтобы сделать то, что я пытаюсь сделать?
Возможно, я упускаю что-то очевидное, но поскольку вы хотите найти менеджеров по найму, почему бы вам просто не передать подкласс HiringManager
в качестве класса в Criteria
?
На всякий случай, существует специальное свойство class
, которое можно использовать для ограничения запроса подтипом. Из справочной документации по Hibernate:
14.9. Предложение where
...
Специальное свойство
class
получает доступ к к значению дискриминатора экземпляра в случае полиморфной персистентности. Имя класса Java включенное в предложение where, будет переведено в его значение дискриминатора.from Cat cat where cat.class = DomesticCat
Вы можете использовать это специальное свойство класса и в Criteria API, но с небольшим изменением: вы должны использовать значение дискриминатора в качестве значения.
c.add(Restrictions.eq("class", "HIRING_MANAGER"));
В отличие от HQL, похоже, что Hibernate не выполняет перевод с Criteria API. Мне не очень нравится идея использования значения дискриминатора в коде, и, возможно, есть другой более чистый способ, но я о нем не знаю. Но это работает.