JSON возвращает вложенные массивы вместо объектов [Spring boot + JPA + MySQL + REST] - PullRequest
0 голосов
/ 03 октября 2018

ВЫПУСК

Здравствуйте, ребята, пожалуйста, помогите мне решить эту проблему.Я начал создавать REST API и столкнулся с проблемой при тестировании созданных мной URL.Пример: когда я отправляю запрос, чтобы получить список из одного объекта, запрос работает нормально, но синтаксис данных, возвращаемый JSON, уродлив: в результате я получил вложенные массивы вместо одного глобального массива, содержащего внутри себя объекты json.Проверьте мой код, пожалуйста, теперь у меня есть 2 сущности, одна из которых зависит от другой, я использовал @OneToMany для установления связей между ними, и никакой ошибки не произошло.Заранее спасибо.

РЕШЕНИЕ

Проблема в том, что мой запрос возвращал список списков по умолчанию, поэтому мне пришлось изменить свой запрос, добавив вызов конструктора,проверьте эти ссылки, пожалуйста: используя новое ключевое слово в HQL-запросе

Также я добавил аннотацию @JsonIgnore, чтобы игнорировать некоторые свойства в моих сущностях, чтобы предотвратить их показ.Теперь данные отображаются в том формате, в котором я хочу: D спасибо за вашу помощь. Проверьте новый результат здесь

Обновление

Здравствуйте еще раз, я недавно понял, что неправильно использовать аннотацию @JsonIgnore для предотвращения отправки некоторых свойств в ответе Jsonи лучший способ настроить свойства для отправки - использовать класс DTO.Еще раз спасибо kj007

Сущность 1

import java.util.List;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.OneToMany;
import javax.persistence.Table;

import lombok.Data;

 @Data
    @Table(name = "x_assureurs") // this is the table name in DB
    @Entity(name = "Assureurs") // This tells Hibernate to make a table out of this class
    public class Assureurs {

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

        @Column(name = "nom_assureur")
        private String name;

        @OneToMany(mappedBy="assureur",fetch = FetchType.LAZY)
        private List<Contrats> contrats;

    }

Сущность 2

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Table;

import lombok.Data;

@Data
@Table(name = "contrats") // this is the table name in DB
@Entity(name = "Contrats") // This tells Hibernate to make a table out of this class
public class Contrats {

    @Id
    @Column(name = "id")
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Integer id;

    @Column(name = "num_contrat")
    private String num;

    @Column(name = "nom_police")
    private String nomPolice;

    @ManyToOne
    @JoinColumn(name = "courtier")
    private Courtiers courtier;

    @ManyToOne
    @JoinColumn(name = "assureur")
    private Assureurs assureur;

}

Репозиторий

import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
import org.springframework.stereotype.Repository;

import tn.igase.gestdoc.models.entities.Assureurs;

// This will be AUTO IMPLEMENTED by Spring into a Bean called assureurRepository

@Repository
public interface AssureurRepository extends JpaRepository<Assureurs, String> {

    // CONSTANTS
    String FIND_ALL_BY_CONTRATS = "SELECT DISTINCT(contrat.assureur.id) as n_assureur, assureur.name \n"
            + " FROM Contrats contrat \n" + " JOIN Assureurs assureur ON contrat.assureur.id = assureur.id ";
    String BY_ONE_COURTIER = "WHERE contrat.courtier.id = :idCourtier";

    // QUERIES
    @Query(FIND_ALL_BY_CONTRATS)
    Iterable<Assureurs> findAllByContrats();

    @Query(FIND_ALL_BY_CONTRATS + BY_ONE_COURTIER)
    Iterable<Object> findAllByContratsAndCourtier(@Param("idCourtier") int idCourtier);

}

Сервис

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import tn.igase.gestdoc.daos.AssureurRepository;
import tn.igase.gestdoc.models.entities.Assureurs;

@Service
public class AssureurService {

   @Autowired
   AssureurRepository assureurRepository;   

   public Iterable<Assureurs> findAllByContrats() {
        return assureurRepository.findAllByContrats();
    }
}

Контроллер

import java.util.ArrayList;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;

import tn.igase.gestdoc.models.entities.Assureurs;
import tn.igase.gestdoc.service.AssureurService;
import tn.igase.gestdoc.service.ContratService;

/**
 * 
 * Assureur controller
 * 
 * @author fre
 */
@RestController
@RequestMapping(path = "/api/assureurs")
public class AssureurController extends MainController {

    @Autowired
    private AssureurService assureurService;
    /**
     * Revert all assureurs that all have contrats
     * 
     * @return list
     */
    @RequestMapping(path = "/all", produces=MediaType.APPLICATION_JSON_VALUE)
    public Iterable<Assureurs> getAll() {
        // This returns a JSON or XML with the users

        Iterable<Assureurs> assureurs = new ArrayList<>();
        assureurs = assureurService.findAllByContrats();
        return assureurs;
    }
}

Результат Проверьте возвращаемые здесь данные JSON

1 Ответ

0 голосов
/ 03 октября 2018

Ваш текущий HQL будет возвращать список объектов, поэтому вы видите результат, подобный этому.

вы можете вернуть либо сущность, либо ID (тип) из запроса HQL или JPA с именем..

Чтобы получить список объектов, вы можете сделать это несколькими способами.

  1. Поскольку HQL будет повторно запускать список объектов, вы можете проанализировать объект в соответствии ск вашей потребности в методе класса обслуживания.

    @Query(FIND_ALL_BY_CONTRATS)
    List<Object> findAllByContrats();
    

2.Используйте DTO (что является наилучшим способом)

STEP1: Создайте DTO для нужных вам проецируемых столбцов, убедитесь, что конструкция соответствует параметрам, требуемым из hql .. например ..

@Data
public class AssureursDTO {

    private Long n_assureur;

    private String name;

    public AssureursDTO(Long n_assureur, String name) {
        this.n_assureur = n_assureur;
        this.name = name;
    }
}

ШАГ 2: определите свой HQL следующим образом, передав полный путь к пакету DTO, используйте ваш

String FIND_ALL_BY_CONTRATS = "SELECT DISTINCT new com.example.demomysql21.entity.AssureursDTO(assureur.id as n_assureur, assureur.name) \n"
            + " FROM Contrats contrat \n" + " JOIN Assureurs assureur ON contrat.assureur.id = assureur.id";

ШАГ 3: Теперь он вернет вам СПИСОК

@Query(FIND_ALL_BY_CONTRATS)
List<AssureursDTO> findAllByContrats();
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...