Home > database >  Can I find by a list of IDs instead the classic findById() in Spring Data JPA?
Can I find by a list of IDs instead the classic findById() in Spring Data JPA?

Time:02-10

I am working on a Spring Boot project using Spring Data JPA and I am wondering if exist a nice and elegant solution to the following use case.

Originally I had a service method like this (it works fine):

@Override
public Page<LogDTO> findAll(Integer logType, LocalDateTime startDate, LocalDateTime endDate, Pageable pageable) throws NotFoundException {

    if(startDate == null) startDate = LocalDateTime.of(1900,1,1,0,0,0);
    if(endDate == null) endDate = LocalDateTime.now();

    Page<EventLog> eventLogs = null;
    if(logType != null) {
        Optional<LogType> logTypeEntity = logTypeRepository.findById(logType);
        logTypeEntity.orElseThrow(  () -> new NotFoundException(String.format("Log type doesn't exists with id: ", Integer.toString(logType))));
        eventLogs = logRepository.findByLogTypeAndTimestampBetween(logTypeEntity.get(),startDate,endDate, pageable);
    } else {
        eventLogs = logRepository.findByTimestampBetween(startDate,endDate,pageable);
    }
    return eventLogs.map(m -> conversionService.convert(m, LogDTO.class));
}

As you can see in this old method take this Integer logType input parameter representing the ID of single log type. Then retrieve the related LogType object by:

 Optional<LogType> logTypeEntity = logTypeRepository.findById(logType);

and uses this logTypeEntity instance in order to retrieve all the EventLog object related to this specific single retrieve LogType, by this line:

eventLogs = logRepository.findByLogTypeAndTimestampBetween(logTypeEntity.get(),startDate,endDate, pageable);

Now I was refactoring this method in order to try to obtains the logs related to multiple LogType. So I am changing my original service method in this way:

@Override
public Page<LogDTO> findAll(List<Integer> logTypesList, 
                            LocalDateTime startDate, 
                            LocalDateTime endDate, 
                            Pageable pageable) throws NotFoundException {

    if(startDate == null) startDate = LocalDateTime.of(1900,1,1,0,0,0);
    if(endDate == null) endDate = LocalDateTime.now();

    Page<EventLog> eventLogs = null;
    
    if(logTypesList != null & logTypesList.size() > 0) {
        
        Optional<LogType> logTypeEntity = logTypeRepository.findById(logType);
        
        logTypeEntity.orElseThrow(  () -> new NotFoundException(String.format("Log type doesn't exists with id: ", Integer.toString(logType))));
        
        eventLogs = logRepository.findByLogTypeAndTimestampBetween(logTypeEntity.get(),startDate,endDate, pageable);
        
    } else {
        eventLogs = logRepository.findByTimestampBetween(startDate,endDate,pageable);
    }
    return eventLogs.map(m -> conversionService.convert(m, LogDTO.class));
}

As you can see my service method now take a List logTypesList parameter instead a single Integer logType). Then in my code I am checking if this list contains element.

Now I am wondering if exist a smart way in Spring Data JPA to replace this line:

Optional<LogType> logTypeEntity = logTypeRepository.findById(logType);

in order to retrieve the collection of the LogType belonging to all the IDs contained into my List logTypesList. I know that I can simply interate on this collection and add the retrieved objects to a result list but I am wondering if I can implement this behavior in a smarter way.

Following a similar doubt related to how to replace in a smart and elegant way this line:

            eventLogs = logRepository.findByLogTypeAndTimestampBetween(logTypeEntity.get(),startDate,endDate, pageable);

Exist a way to pass a collection of LogType objects in order to retrieve all the returned LogEvent objects?

CodePudding user response:

This one (findAllById) should work

List<T> findAllById(Iterable<ID> var1);

CodePudding user response:

Please look at session.byMultipleIds multiLoad

https://docs.jboss.org/hibernate/orm/5.2/javadocs/org/hibernate/Session.html

It will be something like:

List<LogType> logTypes = session.byMultipleIds( LogType.class ).multiLoad( 1L, 2L, 3L );
  • Related