11

Generally we write the query as

@Query("SELECT a FROM Foo a WHERE a.someId = :id")
Map<Long, Foo> findAllBySomeId(Long id)

Is there a way to get it HashMap instead of List.
I want the key of the Hashmap's key=someId and Value as Foo.

I tried like this

@Query("SELECT new map (a.someId, a) FROM Foo a WHERE a.someId = :id")
Map<Long, Foo> findAllBySomeIdAsMap(Long id);

but it returned two items but a.someId as Value and key as 0;

0=someId
1=Foo
Paul
  • 187
  • 1
  • 2
  • 12
  • possible duplicate of [how to return Map with HQL](http://stackoverflow.com/questions/7876724/how-to-return-mapkey-value-with-hql) – Alexis Murray Feb 12 '15 at 02:27
  • That may be little different where it is doing with annotation with 1-many relations. But what I need is using the same (within single) table – Paul Feb 12 '15 at 05:11
  • @Paul did you find the way of getting the hashmap then? I need to do the same so. – Kaizar Laxmidhar Oct 22 '15 at 13:17
  • Possible duplicate of [How to query for Map values with Spring Data JPA?](http://stackoverflow.com/questions/26245351/how-to-query-for-map-values-with-spring-data-jpa) – Marty Pitt Jul 28 '16 at 20:35
  • Possible duplicate of [Can JPA return results as a map?](https://stackoverflow.com/questions/4371384/can-jpa-return-results-as-a-map/8197091) – Javier Heisecke Jul 17 '19 at 14:42

2 Answers2

3

Did you look at this post ?

Also, in this try, your are still looking for a List:

@Query("SELECT new map (a.someId, a) FROM Foo a WHERE a.someId = :id")
List<Foo> findAllBySomeIdAsMap(Long id);

Did you try to change the signature ?

Community
  • 1
  • 1
lgd
  • 1,172
  • 9
  • 10
  • Sorry it was my typo. signature is Hashmap. I will edit the post. But the problem is still the same – Paul Feb 13 '15 at 18:01
  • OK. Did you check out the post ? If so, did it help in your case ? – lgd Feb 13 '15 at 19:32
  • thanks for your response. I did look at the post. In the post the query is trying to check return the result only the value is present in map. But what I need is a way to specify "column-1" is your Key and Value is the Entity for that table – Paul Feb 13 '15 at 22:23
1

I've tackled a similar mapping problem (where I wanted to load every value in a static data table as I know I'll need them all in a process). So this is my solution to this problem (admittedly without the 'where a.someId = id'). It uses findAll(), I'm sure it could use any other 'find' method with your id limitation.

public interface FooRepository extends JpaRepository<Foo, String> {

    // convenience method to provide a 'code -> object' mapping of all Foos
    default Map<String, Foo> mapAll() {
        return findAll().stream().collect(Collectors.toMap(o -> o.getCode(), o -> o));
    }
}
Ben Ketteridge
  • 96
  • 2
  • 10
  • 2
    tragic performance, I hope you dont run this code on production? – agilob Jul 02 '19 at 07:13
  • In what way? It should only be called once to load an entire table, and the DB access & entity mapping is by far the heaviest part of the process. If you're concerned about hitting the DB every time the method is called (which would be a sub-optimal use of the method anyway), add an @Cacheable annotation to it. – Ben Ketteridge Jul 03 '19 at 08:12
  • Why it's wrong and bad: if `o.getCode()` is not unique value for different `o` objects, this code will crash in java, you're not handling non-duplicated `code` value anywhere and not handling Java exception. You're doing job in Java which can be done much, much more efficiently in database in a way OP suggested above. Cacheable shouldn't be used on `T extends JpaRepository` but on `TService`. Your code relies on your undocumented contract which might work for you, but it's bad for everyone else. – agilob Jul 03 '19 at 11:18
  • 1
    I'm sorry if I suggested a simple solution that makes a few assumptions. I was assuming that the reader would understand the implications of indexing the collection on a particular property (getCode() in my example) would require a unique value -> object mapping. And that a programmer would understand that you don't deliberately do a full table scan & load ever 100ms. /s – Ben Ketteridge Jul 04 '19 at 12:27