Каков наилучший способ получить список из интерфейса репозитория в класс списка DTO - PullRequest
0 голосов
/ 01 сентября 2018

Существует имя класса DailyElectricity, которое находится в пакете DTO и содержит Макс, мин, сумма, среднее с геттером и сеттером

public class DailyElectricity implements Serializable {

  private static final long serialVersionUID = 3605549122072628877L;


  private LocalDate date;

  private Long sum;

  private Double average;

  private Long min;

  private Long max;


}

есть интерфейс, работа которого заключается в получении данных из базы данных

@RestResource(exported = false)
public interface HourlyElectricityRepository 
    extends PagingAndSortingRepository<HourlyElectricity,Long> {
  Page<HourlyElectricity> findAllByPanelIdOrderByReadingAtDesc(Long panelId,Pageable pageable);


  @Query("SELECT max(a.generatedElectricity), sum(a.generatedElectricity),min(a.generatedElectricity),max(a.generatedElectricity)  from HourlyElectricity a where DATE_FORMAT(reading_at,'%Y-%m-%d')=DATE_FORMAT(CURDATE()-1,'%Y-%m-%d') and  panel_id=:panelId")
  List<DailyElectricity> getStaticsDailyElectricity(@Param("panelId")Long panelId);

}

это без каких-либо исключений, но когда я вызываю API, это дает

org.springframework.core.convert.ConverterNotFoundException: No converter found capable of converting from type [org.springframework.data.jpa.repository.query.AbstractJpaQuery$TupleConverter$TupleBackedMap] to type [com.techtrial.dto.DailyElectricity]

не может быть преобразован в класс

Ответы [ 2 ]

0 голосов
/ 01 сентября 2018

Если вы используете проекции на основе классов (DTO), они должны содержать конструктор. Попробуйте добавить его в свой DTO.

Но лучше использовать Ломбок , чтобы избежать шаблонного кода:

@Value
public class DailyElectricity {
  private LocalDate date;
  private Long sum;
  private Double average;
  private Long min;
  private Long max;
}

Другой способ - использовать проекции на основе интерфейса :

public interface DailyElectricity {
  LocalDate getDate();
  Long getSum();
  Double getAverage();
  Long getMin();
  Long getMax();
}

ИМО, лучше их использовать, потому что они проще и имеют некоторые преимущества (см. Прилагаемое руководство).

Обратите внимание, что при использовании проекций рекомендуется использовать псевдонимы в запросах. Они должны совпадать с соответствующими именами полей / получателями в проекции, например:

"select max(a.generatedElectricity) as max, ..."

ОБНОВЛЕНО

К сожалению, в Spring Boot 2.0+ проекции на основе классов не работают как ожидаемые (в отличие от SB 1.5+ - см. Может работать demo ). Пока эта ошибка не будет исправлена, мы можем использовать конструктор DTO в запросе .

ОБНОВЛЕНО 2

Я ошибся - когда мы используем проекции на основе классов с пользовательским запросом, мы должны использовать его конструктор независимо от версии Spring Boot .

0 голосов
/ 01 сентября 2018

Проблема в том, что у Spring нет способа выяснить, как преобразовать результат вашего запроса в пользовательский объект DailyElectricity , от которого вы ожидаете; чтобы сделать это отображение возможным, вам нужно сделать две вещи:

  1. создайте конструктор, чтобы вы могли создать новый объект и инициализировать его через значение, полученное в каждой строке вашего запроса:

    public DailyElectricity (Long max,Long sum,Long min,Double average){    
        this.sum=sum;
        this.average=average;
        this.min=min;
        this.max=max;   
    }
    
  2. , затем используйте следующую структуру для запроса в HourlyElectricityRepository

    @Query("SELECT new com.example.DailyElectricity( max(a.generatedElectricity), sum(a.generatedElectricity),min(a.generatedElectricity),avg(a.generatedElectricity))  from HourlyElectricity a where DATE_FORMAT(reading_at,'%Y-%m-%d')=DATE_FORMAT(CURDATE()-1,'%Y-%m-%d') and  panel_id=:panelId")
       List<DailyElectricity> getStaticsDailyElectricity(@Param("panelId")Long panelId);
    
    • Обратите внимание на имя пакета, которое я использовал в запросе ( com.example.DailyElectricity ), и убедитесь, что вы используете правильное имя пакета, соответствующее вашему проекту, перед тестированием.
...