Результат запроса в формате JSON (пара ключ-значение) при использовании аннотации @Query в Spring Boot, Hibernate - PullRequest
0 голосов
/ 10 ноября 2018

Мой контроллер

@GetMapping(value="/getAllDetails")
public List<PriceListEntity> getAllDetails() {
    return MyRepository.getAllDetails();
}

Мой репозиторий

@Repository
public interface MyRepository extends CrudRepository<TestNativeQ, String> {
    @Query( value="SELECT qplt.name price_list_name,  qplab.status_code, qplab.start_date, (SELECT charge_definition_code FROM oalfsaas_repl.QP_CHARGE_DEFINITIONS_B WHERE charge_definition_id=qplab.charge_definition_id  ) chargedefinitioncode "
            + "FROM  PriceListEntity qplab, PriceListLineEntity qplt "
            + " WHERE qplab.price_list_id  =qplt.price_list_id ", nativeQuery = false)
    public List<PriceListEntity> getAllDetails();
}

Фактический результат:

[{"ABC", "DEF", "15/05/2018", "XXZ"}]

Ожидаемый результат

[{name: "ABC", statuscode: "DEF", startDate: "15/05/2018", chargedefintioncode: "XXZ"}]

Запрос имеет соединение с более чем одной таблицей, а также подзапрос на уровне столбца.

1 Ответ

0 голосов
/ 10 ноября 2018

Вы фактически делаете проекцию с вашим выбором, который не возвращает никакого конкретного объекта, но кортеж , который является массивом объектов, которые вы выбираете в своем запросе. Каким бы способом ни был создан JSON, нет имен, есть только значения.

Вам необходимо создать DTO для хранения значений, которые вы хотите передать именами в вашем JSON.

Минимальный пример, имеющий простую сущность, такую ​​как:

@Entity
@Getter
@RequiredArgsConstructor
public class TestClass {
    @Id
    @GeneratedValue
    private Long id;

    @NonNull
    private String a,b,c;
}

и готовы передать - например - только a & b там может быть DTO вроде:

@RequiredArgsConstructor
public class TupleDto {
    @NonNull
    private String a,b;
}

а в вашем случае какой-то PriceListDetailsDto

хранилище может быть объявлено как:

public interface TestClassRepository extends CrudRepository<TestClass, Long> {

    @Query(value="SELECT new org.example.TupleDto(tc.a, tc.b) FROM TestClass tc")
    List<TupleDto> fetchAB();

}

ПРИМЕЧАНИЕ : выше используется оператор new и полный путь к конструктору сущности.

Таким образом, репозиторий Spring знает, как назначать выбранные поля, и при создании JSON из этого DTO получаются поля с именами (имена в DTO).

Оператор new в JPQL просто вызывает new в java. Таким образом, любые данные строки a,b,c могут использоваться для создания объекта Java с конструктором класса этого объекта, принимающим то же количество параметров и типы (и в том же порядке ) так liie new MyEntityObject(a,b,c).

ПРИМЕЧАНИЕ. ТАКЖЕ : в этом простом случае исходная сущность могла бы использоваться как DTO, если бы она была изменена, чтобы разрешить нулевое значение в c и добавить соответствующий конструктор. В вашем случае, когда ваш кортеж состоит из множества таблиц, вам нужно создать DTO для хранения этих значений.

...