SQLNative запрос возвращает пустые результаты - PullRequest
0 голосов
/ 27 мая 2019

Я пытаюсь выполнить запрос, который требует 4 таблицы:

    @Query(value="SELECT e.* FROM erreur e, synop sy, synop_decode sd, station st WHERE e.id_synop = sd.id_synop_decode "
            + "and sd.id_synop_decode = sy.id_synop" + " and DATE(sy.date)= :date and "
                    + "sy.id_station = st.id_station and st.id_station= :stationId", nativeQuery=true)
    public List<Erreur> recherche(@Param("date") Date date, @Param("stationId") Long stationId);

Этот запрос работает нормально и родной sql, я передаю существующий идентификатор станции и дату, как показано ниже:

SELECT e.* FROM erreur e, synop sy, synop_decode sd, station st WHERE e.id_synop = sd.id_synop_decode and sd.id_synop_decode = sy.id_synop
            and DATE(sy.date)= '2019-05-27' and sy.id_station = st.id_station and st.id_station= 60355;

Этот запрос прекрасно работает в Mysql Workbench.

Вот фактический контроллер, который я использую для целей тестирования:

@GetMapping("/station/{stationId}/erreurs/today")
    public List<Erreur> getTodayErreurByStationId(@PathVariable Long stationId)
    {
        List<Erreur> erreurs = new ArrayList<Erreur>();
        Optional<Station> stationOptional = stationRepository.findById(stationId);
        if(stationOptional.isPresent())
        {
            return erreurRepository.recherche(new Date(), stationId);
        }
        return null;
    }

Ожидаемые результаты - фактические объекты "Ererur" вмой список массивов, но RestClient просто возвращает пустой массив [], в то время как запрос работает в MySQL, как я описал выше.

Итак, мой вопрос: как я могу написать этот запрос на языке Hql так, чтобыя могу вернуть нужные лица.Или как я могу сопоставить мои результаты sql с моим целевым настраиваемым calss "Erreur"?

@Entity
@Getter @Setter @NoArgsConstructor
@Table(name="erreur")
public class Erreur {

    public Erreur(int section, int groupe, String info) {
        this.section = section;
        this.groupe = groupe;
        this.info = info;
    }

    @Id
    @GeneratedValue(strategy=GenerationType.IDENTITY)
    @Column(name="id_erreur")
    private Long id;

    @ManyToOne(cascade= {CascadeType.DETACH,CascadeType.MERGE,CascadeType.PERSIST,CascadeType.REFRESH}, 
    fetch=FetchType.LAZY)
    @JsonIgnore
    @JoinColumn(name="id_synop")
    private SynopDecode synopDecode;

    @OneToOne
    @JoinColumn(name="id_controle")
    private Controle controle;

    @ManyToOne(cascade= {CascadeType.DETACH,CascadeType.MERGE,CascadeType.PERSIST,CascadeType.REFRESH}, 
            fetch=FetchType.LAZY)
    @JsonIgnore
    @JoinColumn(name="id_station")
    private Station station;

    @Column(name="section")
    private int section;

    @Column(name="groupe")
    private int groupe;

    @Column(name="info")
    private String info;
}

Ответы [ 3 ]

0 голосов
/ 28 мая 2019

Если вы хотите использовать соглашение jpa напрямую, то вам придется создавать ассоциации между различными сущностями, то есть как связаны две сущности.Когда мы определяем эти ассоциации, тогда Spring jpa знает, как преобразовать имя метода или пользовательские запросы в SQL.

Ваш код должен выглядеть примерно так:

public class Erreur {
...
@ManyToOne
@JoinColumns//define how Erreur and SynopeDecone are linked
private SynopDecode synopDecode;
...
public class SynopDecode {
...
@ManyToOne // or @OneToOne its not mentioned in question how these two are linked
@JoinColumns//define how SynopDecode and Synop are linked
private Synop synop;
...

Тогда вы можете написатьВаш запрос как

@Query("select e from Erreur e LEFT JOIN e.synopDecode sy LEFT JOIN sy.synop sy WHERE DATE(sy.date) = :date AND sy.id_station = :stationId")
List<Erreur> getByDateAndStationId(@Param("date") Date date, @Param("stationId") Long stationId)

Вы не можете использовать запрос на основе имени метода, потому что хотите использовать функцию SQL, чтобы соответствовать только части даты «date», а не всей отметке времени.

0 голосов
/ 29 мая 2019

Я нашел способ получить те же результаты, что и мой SQL-запрос, используя аннотацию @Query и доступ к свойствам объекта, например так:

    @Query("from Erreur e where e.synopDecode.synop.station.id = :stationId and "
            + "DATE(e.synopDecode.synop.date) = :date")
    public List<Erreur> recherche(@Param("date") Date date, @Param("stationId") Long stationId);

Я думаю, что это решает мою проблему, спасибо за помощь

0 голосов
/ 27 мая 2019

Вы можете использовать методы jpa по соглашениям.
Предполагая, что SynopDecode имеет такое свойство, как:

//SynopDecode class

@ManyToOne
private Synop synop;
//repository interface

List<Erreur> findByStationIdAndSynopDecodeSynopDate(Long stationId, Date date);
//or
//List<Erreur> findByStationIdAndSynopDecode_Synop_Date(Long stationId, Date date);

ОБНОВЛЕНИЕ
Как Punit Tiwan (@punit-tiwan) обратите внимание, что вышеперечисленные методы используются для определенной даты.
Вы можете использовать методы ниже только для ДАТЫ.

//repository interface

List<Erreur> findByStationIdAndSynopDecodeSynopDateBetween(Long stationId, Date startOfDate, Date endOfDate);
//or
//List<Erreur> findByStationIdAndSynopDecode_Synop_DateBetween(Long stationId, Date startOfDate, Date endOfDate);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...