Projections du spring ne retournant pas l’état Détails

J’ai une table de pays et d’état pour laquelle j’ai intégré Spring Data JPA. J’ai créé une fonction public Page getAllCountryDetails dans mon CountryServiceImpl pour obtenir tous les détails du pays et de l’État correspondant. Le service fonctionne bien et me donne la sortie ci-dessous:

 { "content": [ { "id": 123, "countryName": "USA", "countryCode": "USA", "countryDetails": "XXXXXXXX", "countryZone": "XXXXXXX", "states": [ { "id": 23, "stateName": "Washington DC", "countryCode": "USA", "stateCode": "WAS", "stateDetails": "XXXXX", "stateZone": "YYYYYY" }, { "id": 24, "stateName": "Some Other States", "countryCode": "USA", "stateCode": "SOS", "stateDetails": "XXXXX", "stateZone": "YYYYYY" } ] } ], "last": false, "totalPages": 28, "totalElements": 326, "size": 12, "number": 0, "sort": null, "numberOfElements": 12, "first": true } 

Mon code complet est comme indiqué ci-dessous:

CountryRepository.java

 @Repository public interface CountryRepository extends JpaRepository { @Query(value = "SELECT country FROM Country country GROUP BY country.countryId ORDER BY ?#{#pageable}", countQuery = "SELECT COUNT(*) FROM Country country GROUP BY country.countryId ORDER BY ?#{#pageable}") public Page findAll(Pageable pageRequest); } 

CountryServiceImpl.java

 @Service public class CountryServiceImpl implements CountryService { @Autowired private CountryRepository countryRepository; @Override public Page getAllCountryDetails(final int page, final int size) { return countryRepository.findAll(new PageRequest(page, size)); } } 

CountryDetails.java

 @Entity @Table(name = "country", uniqueConstraints = @UniqueConstraint(columnNames = "id")) public class CountryDetails { @Id @GeneratedValue @Column(name = "id", unique = true, nullable = false) private Integer id; private Ssortingng countryName; private Ssortingng countryCode; private Ssortingng countryDetails; private Ssortingng countryZone; @JsonManagedReference @OneToMany(fetch = FetchType.LAZY, mappedBy = "countryDetails") private List states; // getters / setters omitted } 

State.java

 @Entity @Table(name = "state", uniqueConstraints = @UniqueConstraint(columnNames = "id")) public class State { @Id @GeneratedValue @Column(name = "id", unique = true, nullable = false) private Integer id; private Ssortingng stateName; private Ssortingng countryCode; private Ssortingng stateCode; private Ssortingng stateDetails; private Ssortingng stateZone; @JsonBackReference @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "countryCode", nullable = false, insertable = false, updatable = false, foreignKey = @javax.persistence.ForeignKey(name="none",value = ConstraintMode.NO_CONSTRAINT)) private CountryDetails countryDetails; // getters / setters omitted } 

Maintenant le problème

En fait, ce que je veux que le service pays retourne avec un minimum d’informations, comme indiqué ci-dessous

 { "content": [ { "countryName": "USA", "countryCode": "USA", "states": [ { "stateCode": "WAS" }, { "stateCode": "SOS" } ] } ], "last": false, "totalPages": 28, "totalElements": 326, "size": 12, "number": 0, "sort": null, "numberOfElements": 12, "first": true } 

Donc, pour y parvenir, j’ai utilisé des projections comme ci-dessous.

PaysProjection .java

 public interface CountryProjection { public Ssortingng getCountryName(); public Ssortingng getCountryCode(); public List getStates(); } 

StateProjection .java

 public interface StateProjection { public Ssortingng getStateCode(); } 

CountryServiceImpl.java

 @Repository public interface CountryRepository extends JpaRepository { @Query(value = "SELECT country.countryName AS countryName, country.countryCode AS countryCode FROM Country country GROUP BY country.countryId ORDER BY ?#{#pageable}", countQuery = "SELECT COUNT(*) FROM Country country GROUP BY country.countryId ORDER BY ?#{#pageable}") public Page findAll(Pageable pageRequest); } 

Mais maintenant, le service renvoie l’un des détails de l’état, comme indiqué ci-dessous.

 { "content": [ { "countryName": "USA", "countryCode": "USA" } ], "last": false, "totalPages": 28, "totalElements": 326, "size": 12, "number": 0, "sort": null, "numberOfElements": 12, "first": true } 

Comment pouvons-nous obtenir les détails minimaux sur l’état, comme ci-dessous

 { "content": [ { "countryName": "USA", "countryCode": "USA", "states": [ { "stateCode": "WAS" }, { "stateCode": "SOS" } ] } ], "last": false, "totalPages": 28, "totalElements": 326, "size": 12, "number": 0, "sort": null, "numberOfElements": 12, "first": true } 

Quelqu’un peut-il m’aider s’il vous plaît sur ce

Essayez d’utiliser JsonIgnore avec les champs que vous ne voulez pas dans le JSON de retour.

@JsonIgnore

private Ssortingng stateDetails;

use peut utiliser un mot-clé transitoire avec la variable dont vous ne voulez pas le json. ya sinon, utilisez @Expose Ssortingng mySsortingng;

Vous pouvez consulter la documentation d’annotation:

@JsonIgnoreProperties (“fieldname”)

Cette annotation doit être appliquée à vos classes POJO dans votre cas. Pays *, Etat * en mentionnant la liste de champs séparés par des virgules que vous n’avez pas besoin de faire partie de la réponse.

Vous pouvez essayer cette approche au lieu de passer à la mise en œuvre sur le style de projection.

 @JsonIgnoreProperties({ "id","countryDetails","countryZone"}) public class CountryDetails @JsonIgnoreProperties({ "id","stateName","countryCode","stateDetails","stateZone"}) public class State 

Première idée

OMI, il y a quelque chose qui cloche dans votre façon de faire les choses. Je ne comprends pas pourquoi vous définissez la requête directement comme ceci:

 @Query(value = "SELECT country.countryName AS countryName, country.countryCode AS countryCode FROM Country country GROUP BY country.countryId ORDER BY ?#{#pageable}", countQuery = "SELECT COUNT(*) FROM Country country GROUP BY country.countryId ORDER BY ?#{#pageable}") 

qui consiste essentiellement à créer une projection par select .

D’autre part, vous utilisez des projections basées sur une interface qui effectue à nouveau la projection, mais en exposant les accesseurs des propriétés que vous souhaitez projeter. Autant que je sache, vous avez bien défini la hiérarchie via des interfaces et ce devrait être une approche valide.

Ce que je demande, c’est que vous avez essayé de supprimer la partie @Query dans son ensemble?

Deuxième idée (dans l’oeil du commentaire)

Une autre idée peut être d’utiliser la construction join fetch dans jpql qui est utilisée pour indiquer à l’hibernation de charger l’association rapidement avec la requête.

 @Query(value = "SELECT country.countryName AS countryName, country.countryCode AS countryCode, countryStates FROM Country country join fetch country.states countryStates GROUP BY country.countryId ORDER BY ?#{#pageable}"