Jens` answer is absolutely right.
After talks with collegues i ended up with an alternative to his tips.
Since i have 6 search options the query building will be likely a lot of switch blocks.
In short: I did this (not edited or shortened to sketch the complexity of the query):
@Query("""
select p.projectname, p.unit, p.cost_unit as costUnit, p.chapter, u.username, w.firstname, w.lastname, e.comment, e.value, e.entry_date as entry,
w.active_from as activeFrom, w.active_to as activeTo, w.type, w.hwl, w.further, w.compensation, w.delegation, w.amount
from projects p
left join users u on p.users_id = u.id
left join workers w on w.projects_id = p.id
left join entries e on e.workers_id = w.id
where trim(lower(p.projectname)) like concat('%', lower(:projectName))
and trim(lower(concat(w.firstname, w.lastname))) like concat('%', lower(:workerName))
and trim(lower(u.username)) like concat('%', lower(:userName))
and extract(year from e.entry_date) >= :year
and trim(lower(p.cost_unit)) like concat('%', lower(:costUnit), '%')
and trim(lower(p.unit)) like concat('%', lower(:unit), '%')""")
List<SearchResultDto> search(String projectName, String workerName, String userName, Integer year, String costUnit, String unit);
The trick is to use the %
operator for string queries. When the parameter is null or empty string, i'll pass it on to the query.
So %
yields all entries for the given column.
Whereas %projectName
yields all entries with projectName in it.
The same works on year. If a year is selected in the UI, it goes to the query, If not, i use 0
as year so all years will be selected.