Есть ли способ ввести запрос напрямую с помощью HibernateFilter? - PullRequest
1 голос
/ 01 апреля 2020

Мне нужно установить более сложный фильтр гибернации, сформированный из нескольких параметров, которые могут отсутствовать или нет. По сути, я хочу, чтобы мой фильтр вставлял что-то вроде:

shipmentIds in (...) AND cityIds in (....) AND countryIds in (....)

В некоторых ситуациях возможно, что у меня есть только shipmentIds , а введенный запрос должен быть только чем-то вроде

shipmentIds in (...)

И поскольку мой фильтр должен быть довольно динамичным c в зависимости от того, какие идентификаторы я могу предоставить, я попытался сделать следующее, но это не удалось:

    @FilterDefs({
        @FilterDef(name = CUSTOM_FILTER,
                    parameters = { @ParamDef(name = CUSTOM_QUERY, type = "string")})
    })
    @Filters({
        @Filter(name = CUSTOM_FILTER, condition =  " :"+ CUSTOM_QUERY +" ")
    })
    public class MyClass { ... }

Мой фильтр logi c :

org.hibernate.Filter filter = entityManager.unwrap(Session.class).enableFilter(CUSTOM_FILTER);
//customQuery contains the condition that I need to inject
filter.setParameter(CUSTOM_QUERY, customQuery); 
filter.validate();

Исключение, которое я получаю, это:

org.postgresql.util.PSQLException: ERROR: argument of AND must be type boolean, not type character varying_

Я подозреваю, что это происходит из-за type = "string" , используемого моим фильтр. То есть используется StringType из hibernate, который оборачивает мой запрос запятыми:

return '\'' + value + '\'';  

Так есть ли способ динамически внедрить такой запрос, или я должен определить несколько пользовательских фильтров для каждого комбинация между идентификаторами?

1 Ответ

0 голосов
/ 03 апреля 2020

Мне наконец удалось найти решение этой проблемы, поэтому я добавлю ответ здесь.

Так есть ли способ динамически внедрить такой запрос, или я должен определить несколько пользовательских фильтров для каждой комбинации между идентификаторами?

Решение здесь не в том, чтобы динамически вставлять один запрос, так как это все еще невозможно, но для определения нескольких фильтров, не пользовательских для каждой комбинации, а просто простых фильтров для каждого из них. Затем мы в основном активируем любой из них, который нам нужен, и таким образом в конечном запросе будут предложения для любых идентификаторов, которые мы можем предоставить.

Код выглядит примерно так:

@FilterDefs({
        @FilterDef(name = CITY_FILTER, parameters = {@ParamDef(name = CITY_IDS_PARAM, type = "long")}),
        @FilterDef(name = COUNTRY_FILTER, parameters = {@ParamDef(name = COUNTRY_IDS_PARAM, type = "long")}),
        @FilterDef(name = SHIPMENT_FILTER, parameters = {@ParamDef(name = SHIPMENT_IDS_PARAM, type = "long")})
})
@Filters({
        @Filter(name = CITY_FILTER, condition = "cityIds in(:" + CITY_IDS_PARAM + ")"),
        @Filter(name = COUNTRY_FILTER, condition = "countryIds in(:" + COUNTRY_IDS_PARAM + ")"),
        @Filter(name = SHIPMENT_FILTER, condition = "shipmentIds in(:" + SHIPMENT_IDS_PARAM + ")")
})
public class MyClass { ... }

Примечание : CITY_FILTER, CITY_IDS_PARAM et c. просто простые уникальные константные строки, используемые для правильной загрузки фильтров.

Logi c:

public void applyFiltering() {
    // ... rest of the code to retrieve the set of ids
    createFilterFor(cityIds, CITY_FILTER, CITY_IDS_PARAM);
    createFilterFor(countryIds, COUNTRY_FILTER, COUNTRY_IDS_PARAM);
    createFilterFor(shipmentIds, SHIPMENT_FILTER, SHIPMENT_IDS_PARAM);
}

private void createFilterFor(final Set<Long> ids, final String filterName, final String paramName) {
    if(CollectionUtils.isNotEmpty(ids)) {
        org.hibernate.Filter filter = entityManager.unwrap(Session.class).enableFilter(filterName);
        filter.setParameterList(paramName, ids);
        filter.validate();
    }
}

Используя вышеприведенное, последний запрос может закончиться дополнительные условия, например

shipmentIds in (...) AND cityIds in (....) AND countryIds in (....)

или

shipmentIds in (...) AND cityIds in (....)

или только отдельные.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...