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 );