Reputation: 670
Suppose I have a table which contains all the accounts of user and type. I want to make a Jpa Repository method which returns an array of total number of each type of user (USER, ADMIN, MASTER).
Here is how I did it in JpaRepository:
@Query(value="SELECT (SELECT COUNT(*) FROM account WHERE account_role='USER'),"
+ "(SELECT COUNT(*) FROM account WHERE account_role='ADMIN'),"
+ "(SELECT COUNT(*) FROM account WHERE account_role='MASTER')"
+ "FROM account LIMIT 1",
nativeQuery=true)
public List<Integer> getTotalAccountType();
The code executed fine, but the result wasn't what I expected.
Result:
[2]
Expected result: [2,10,30]
Any idea how would I use nested SQL with JPQL? Thank you in advance!
Upvotes: 1
Views: 319
Reputation: 2851
If repository method returns List of Integers it means that query result row contains an Integer value. But you expect to get sequence of Integers in one row.
You can get same result different way:
@Query(value="SELECT COUNT(*) FROM account WHERE account_role=?", nativeQuery=true)
public Integer getTotalAccountType(String role);
and then:
Integer userCount = repository.getTotalAccountType("USER");
Integer adminCount = repository.getTotalAccountType("ADMIN");
Integer masterCount = repository.getTotalAccountType("MASTER");
or if you have mapped entity:
Pair<K,V>
class with constructor Pair(K key, V value)
or use it from any external libraryrepository method based on hql query
@Query(value="select new javafx.util.Pair(a.accountRole, count(a)) from Account a group by a.accountRole")
public List<Pair<String, Integer>> getRoleCountList();
convert repository result to a Map<String, Integer>
in service
javafx.util.Pair<String, Integer> result = repository.getRoleCountList();
Map<String, Integer> map = result.stream().collect(Collectors.toMap(r-> r.getKey(), r-> r.getValue()));
Upvotes: 2
Reputation: 152
Try returning Object[]
rather than a List<Integer>
. I think returning List<Integer>
would indicate multiple rows of an Integer
value are being returned, whereas you're getting back one row with multiple Intger
columns.
From the resulting Object[]
you would pull out the first value (indicating a row). This should be another Object[]
, which will have your values in the order returned.
You can also remove that last "FROM account LIMIT 1"
line, as it has no bearing on the result.
I would recommend casting all of this to an object though. As seen here - How to return a custom object from a Spring Data JPA GROUP BY query
Upvotes: 0