Hibernate Subqueries.exists - PullRequest
       6

Hibernate Subqueries.exists

1 голос
/ 07 февраля 2012

У меня проблема с критериями Subqueries.exists.

У меня есть следующее:

DetachedCriteria criteria = DetachedCriteria.forClass(Expense.class, "mainExpense")
        .add(Restrictions.eq("group", group))
        .addOrder(Order.desc("created"));

if (all) {
    criteria.add(
            Restrictions.or(
                    Restrictions.eq("status", ExpenseStatus.PENDING),
                    Restrictions.eq("status", ExpenseStatus.COMPLETE)
            ));
} else {
    criteria.add(Restrictions.eq("status", ExpenseStatus.PENDING));
}

if (user != null) {
    DetachedCriteria userSubCriteria = DetachedCriteria.forClass(UserExpense.class, "userExpense")
            .add(Restrictions.eq("userExpense.primaryKey.user", user))
            .add(Restrictions.eq("userExpense.primaryKey.expense", "mainExpense"))
            .setProjection(Projections.property("userExpense.primaryKey"));
    criteria.add(Subqueries.exists(userSubCriteria));
}

return getHibernateTemplate().findByCriteria(criteria);

Если я передаю нулевого пользователя (не использующего Subqueries.exists), онработает хорошо и возвращает мне действительные статьи расходов.Если я дам пользователю, если мне дадут следующее:

org.springframework.orm.hibernate3.HibernateSystemException: не удалось получить значение поля по отражателю getter of Expense.id;Вложенное исключение - org.hibernate.PropertyAccessException: не удалось получить значение поля по получателю отражения Expense.id

и ниже в журналах:

Невозможно установить поле java.lang.Integer Расход.id to java.lang.String

Кто-нибудь имеет представление о том, что я делаю неправильно?

Ответы [ 2 ]

8 голосов
/ 08 февраля 2012

Я думаю, что в запросе есть две проблемы:

  1. Существующий подзапрос должен иметь проекцию, возвращающую один столбец. Вы используете проекцию, которая возвращает внедренный объект.
  2. Вы сравниваете "userExpense.primaryKey.expense" и "mainExpense" с Restrictions.eq(). Я не думаю, что это действительно. Вы должны использовать Restrictions.eqProperty("userExpense.primaryKey.expense.id", "mainExpense.id")
0 голосов
/ 26 сентября 2018

Существует еще один упрощенный пример решения проблемы того же типа.Результатом настройки критериев являются несвязанные множества.View - RegistryViewable (представление объекта), Table - DocumentType (представление объекта), отношение 1: n DocumentType.id: @ManyToOne RegistryViewable.typDokumentu (представление объекта).В сущности класса RegistryViewable есть атрибут typDokumentu DocumentType type.Атрибут systemType имеет логический тип.Очень важным является пункт setProjection, без которого критерии не сработают.

            DetachedCriteria criteria = DetachedCriteria.forClass(RegistryViewable.class, "RegistryViewable");
    ...         
    if (EntityType.DOCUMENT.equals(searchDTO.getTypEntity())) {
                DetachedCriteria docTypeCriteria = DetachedCriteria.forClass(DocumentType.class,
                        "DocumentType");
                docTypeCriteria
                        .add(Restrictions.eq("DocumentType" + "." + "systemType",
                                true))
                        .add(Restrictions.eqProperty("DocumentType" + "." + "id",
                                "RegistryViewable" + "." + "typDokumentu" + "."
                                        + "id"));
                docTypeCriteria.setProjection(
                        Projections.property("DocumentType" + "." + "id"));
                if (searchDTO.isSystemType()) {
                    criteria.add(Subqueries.exists(docTypeCriteria));
                } else {
                    criteria.add(Subqueries.notExists(docTypeCriteria));
                }
            }
...
        List<RegistryViewable> list = repository.findByCriteria(criteria);
...