I'm working on an Admin UI for an authorization server. One of the features is to display a list of who has logged in, and we are doing that by querying a database table where the currently issued refresh tokens are stored. A user can log in from multiple devices to the same application, generating multiple tokens. At the moment the requirements are NOT to break down this view by device, instead if a user has logged in at all, they are to be shown in the list. If we revoke access (one of the other requirements from this UI), then all devices will have their refresh tokens revoked.
Anyway, the main thing tripping me up is the query. I'm writing the query to pull back all the tokens for the specified user, but for each client only the most recent one is retrieved. ie, if there are 5 tokens for a given user/client combination, only the one with the most recent timestamp will be returned to the UI. I'm trying to do this entirely with JPQL in my SpringBoot/Hibernate backend, which is communicating with a Postgres database.
I can write this in SQL several different ways. Here are two forms of the query that return the same results:
select r1.*
from dev.refresh_tokens r1
join (
select r2.client_id, max(r2.timestamp) as timestamp
from dev.refresh_tokens r2
group by r2.client_id
) r3 on r1.client_id = r3.client_id and r1.timestamp = r3.timestamp
where r1.user_id = 1;
select r1.*
from dev.refresh_tokens r1
where r1.user_id = 1
and (r1.client_id, r1.timestamp) in (
select r2.client_id, max(r2.timestamp) as timestamp
from dev.refresh_tokens r2
group by r2.client_id
);
The reason I've figured out multiple ways to do the query is because I'm trying to also figure out how to translate it into JPQL. I avoid doing native queries in Hibernate as much as possible, instead relying on the DB-agnostic JPQL syntax. However, I just can't figure out how to translate this to JPQL.
I know native queries and/or putting filter logic into my Java code are both options. However, I'm hoping this is possible with a standard JPQL query.