Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Spring Data: JPA repository findAll() to return *Map instead of List?

I have a Spring Data JPA repository interface that looks something like this:

@Repository
public interface DBReportRepository extends JpaRepository<TransactionModel, Long> {

    List<TransactionModel> findAll();
    List<TransactionModel> findByClientId(Long id);
}

Is there a workaround to make the same but for a Collection to be returned of type HashMap<K, V>? I've looked through the Spring Data classes and couldn't find anything other than List<> return values.

like image 557
Deniss M. Avatar asked Jan 26 '17 14:01

Deniss M.


People also ask

Can JPA return results as a map?

There is no standard way to get JPA to return a map.

What does findAll return in JPA?

findAll() would return empty.

What is the return type of findAll method in CrudRepository?

The CrudRepository interface declares many methods, but the methods that are relevant for this blog post are described in the following: The void delete(T entity) method deletes the entity whose id is given as a method parameter. The Iterable<T> findAll() method returns all entities that are saved to the database.

How do you return DTOs from native queries with Spring data JPA?

Spring Data JPA doesn't provide an automatic mapping of class-based DTOs for native queries. The easiest way to use this projection is to define your query as a @NamedNativeQuery and assign an @SqlResultSetMapping that defines a constructor result mapping.


2 Answers

I dont think you will find an easier solution as to create a simple one liner to convert your result to a map. It is simple and fast with java 8 lambdas:

Map<Long, Transaction> transactionMap = transactionList.stream()
         .collect(Collectors.toMap(Transaction::getId, Function.identity()));
like image 131
Patrick Avatar answered Oct 19 '22 17:10

Patrick


Just had to solve something similar and Patricks answer helped but it can be improved by indicating where to add it.

To to make it appear like the JPA repo returns a map, an improvement would to wrap this up in a default method in the repository interface. Saves you having to perform a stream in all the consuming classes.

@Repository
public interface DBReportRepository extends JpaRepository<TransactionModel, Long> {

    List<TransactionModel> findAll();

    default Map<Long, TransactionModel> findAllMap() {
        return findAll().stream().collect(Collectors.toMap(TransactionModel::getId, v -> v));
    }

    List<TransactionModel> findByClientId(Long id);

    default Map<Long, TransactionModel> findByClientIdMap(Long id) {
        return findByClientId(id).stream().collect(Collectors.toMap(TransactionModel::getId, v -> v));
    }
}
like image 36
Matt R Avatar answered Oct 19 '22 15:10

Matt R