Получение только значений вместо ключей и значений в ответе JSON при весенней загрузке - PullRequest
1 голос
/ 13 марта 2020

Я пытаюсь получить данные из репозитория с помощью запроса SQL, но я получаю только значения вместо ключей и значений в ответе JSON, когда пытаюсь получить его.

У меня есть следующие классы

Репозиторий

@Repository
public interface ReportingDataRepository extends CrudRepository<Task, String> {
  @Query(name = "task.getReportingData")
  List<Task> getReportingData(String startDate, String endDate);
}

Контроллер

@RequestMapping(path = "/api/{startdate}/{enddate}")
public TaskScores getScoresDataByDate(@PathVariable("startdate") String startDate,
                                    @PathVariable("enddate") String endDate) {
  return new TaskScores((reportingDataRepository.getReportingData(startDate, endDate)));

}

Класс оболочки в контроллере

@Getter
@Setter
@ToString
@AllArgsConstructor
@NoArgsConstructor
@Data
public class TaskScores {
  List<Task> tasks;
}

Entity

@Getter
@Setter
@ToString
@AllArgsConstructor
@NoArgsConstructor
@Entity
@Data

@NamedNativeQuery(
    name = "task.getReportingData",
    query = "SELECT sys.id as id, sys.name as sys, sys.eventtype, workflow_agg.subprocess_id "
            + "FROM daily_agg_counts_system_score as sys_agg "
            + "join system_eventtype as sys on sys_agg.system_id = sys.id "
            + "join system_subprocess_mapping sm on sys_agg.system_id = sm.system_id "
            + "join daily_agg_workflow_completion_score workflow_agg on sm.subprocess_id = workflow_agg.subprocess_id "
            + "join sub_process sp on sp.id = sm.subprocess_id "
            + "join process as p on p.id = sys.process_id "
            + "join flow on flow.id = p.flow_id "
            + "join program on program.id = flow.program_id "
            + "where sys_agg.datepst BETWEEN ?1 AND ?2 "
            + "order by program.id asc, p.flow_id asc, sp.id asc, sys_agg.system_id asc, sys_agg.datepst asc "
            + "limit 1"
    )

    public class Task implements Serializable{
      @Column(name = "id")
      @Id
      private String id;

      @Column(name = "system")
      private String sys;

      @Column(name = "event_type")
      private String eventType;

      @ManyToOne(fetch = FetchType.LAZY)
      private SubProcess subprocessId;

      @Embeddable
      class Score implements Serializable {
      @JsonIgnore
      String score;
    }
 }

Я использую Spring Data JPA. Когда я запускаю этот код, я получаю следующее JSON назад

{ "tasks": [ [ 1, "oms", "BE", 1 ] ] }

, но я хочу, чтобы он был похож на фактический json { "tasks": [ [ "id" : 1, "sys" : "oms", "eventType" : "BE", "subprocessId" : 1 ] ] }

Любая идея, где я иду не так?

Ответы [ 2 ]

1 голос
/ 13 марта 2020

В вашем случае я бы создал класс TaskDto:

package your.package.dto;
@Data
@AllArgsConstructor
public class TaskDto implements Serializable { 
    // all fields 
}

чем, я бы использовал запрос как показано ниже

SELECT new your.package.dto.TaskDto (sys.id, sys.name, sys.eventtype, workflow_agg.subprocess_id)
FROM ...

Обратите внимание, что:

  1. Внутри запрос не используется as;
  2. Запрос не должен native;
1 голос
/ 13 марта 2020

Да, вы используете собственный запрос и пытаетесь сохранить результат в объекте путем сопоставления результата запроса с вашим объектом. К сожалению, это не работает таким образом.

Если вы попытаетесь использовать результат нативного запроса в объекте, вы получите только значения вместо ключей и значений. Чтобы получить ключи и значения, у вас есть два варианта:

Один из способов сделать это - SQLResultsetMapping . См. SQLResultsetMapping , чтобы понять больше.

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

Сначала измените эту строку в вашем запрос :

SELECT sys.id as id, sys.name as sys, sys.eventtype, workflow_agg.subprocess_id

до

SELECT sys.id as id, sys.name as sys, sys.eventtype as eventtype, workflow_agg.subprocess_id as subprocessid

т.е. дать псевдоним всем извлеченным столбцам.

И затем вы создаете интерфейс вот так (это называется интерфейс проекции ):

interface getSysProperties{
    getid();
    getsys();
    geteventtype();
    getsubprocessid();
}

И затем вместо получения вашего SQL результата в объекте, получите его в вашей проекции интерфейса, как :

  @Query(name = "task.getReportingData")
  List<getSysProperties> getReportingData(String startDate, String endDate);
        // ^Projection interface instead of Entity

Этот метод будет работать, если вы хотите только извлечь свои данные SQL, а затем не изменять их в своем коде.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...