I've a database structure built with JPA. To give a little bit context - the user is shown a datatable and some (many...) filters with which he can filter the shown entries of the datatable. For example, every entry of the datatable corresponds to a certain factory (of e.g. 40 factories in total) and the user can filter for one or more factories.
To prevent overhead, the user can only filter by factories which occur in the dataset the datatable is built of, i.e. factories which would give an empty result after filtering (since there aren't any entries with this factory) aren't shown at all in the factory filter.
Furthermore, the datatable is paginated, i.e. just the first (second, third, etc.) 50 entries are given to the frontend but -- and that's the crucial point -- the filters should of course correspond to all entries (i.p. also the entries on the pages which are not shown). That means if factory B only occurs on page 2 and page 1 is loaded (i.e. there is no factory B under the shown entries resp. the entries the frontend receives), the factory filter should still list factory B.
My approach is the following: When constructing the result, using the same sql query, I get all values which one can filter by. So my constructed table looks so to say like this
factory | status | ...
F1 | done | ...
F2 | in progress | ...
F1 | in progress | ...
containing the entries over all pages (of which just the first (second, third, ...) 50 entries are given to the frontend) projected to the properties which one can filter by.
Now I just get the needes values by e.g. SELECT DISTINCT(entry.factory) FROM ...
in a typed query. Basically, at this point I would create a sql view of the constructed table and get then 1) all distinct factories, 2) all distinct statuses, etc. pp. But JPA doesn't allow a CREATE VIEW
when creating a typed query so at the moment, for each column I construct the same table (the one above) and get the distinct values in the current column.
(just for the sake of completeness: for performance reasons, it is not possible to get all entities and then iterate e.g. using the stream API over the list of results mapping to the "filterable" attributes, i.e. filtering has to happen directly in the database using SQL (i guess?))
I have two questions:
- Is this implementation reasonable?
- If yes, how can I approach the idea of creating a view? Ideally, directly via JPA but unfortunately I didn't find a real way to approach this using JPA.
Edit: To break it down to the very basic problem:
QueryPart queryPart = new QueryPartDTO("<some JPA query>");
QueryFactory<MyEntity> queryFactory = new QueryFactory<>();
final TypedQuery<MyEntity> query = queryFactory.buildTypedQuery(queryPart, entityManager, MyEntity.class);
List<MyEntity> resultList = query.getResultList();
// at this point, the query fires ↑
// that's okay because I do need the List<Entity> in order to give it to the frontend
// but instead of just getting a List<MyEntity>,
// I would like to have a sql view containing the result (resp. the whole result) as well
// because moreover, I have to get e.g. all factories, all statuses, etc.
// which occur in the given data - what could of course be done with
// the already given List<MyEntity> using the Stream API but since the list
// is in general very large, this approach would be to inefficient.
// Instead, I would like to do these computations using SQL - but for this,
// I need the data given by the constructed query above in a SQL table.
// Executing the query over and over again (and first, getting all distinct factories,
// second getting all distinct statuses, etc.) is not possible for
// performance reasons - the query is expensive. Hence, I need to
// save the result the query gives - in a way, I can execute some more
// queries on it: a view i guess.
Thanks in advance.