Весенние Прогнозы не возвращают Государственные Детали - PullRequest
0 голосов
/ 31 мая 2018

У меня есть таблица "Страна и штат", для которой я интегрировал с Spring Data JPA.Я создал функцию public Page<CountryDetails> getAllCountryDetails в моем CountryServiceImpl для получения всей страны и соответствующих сведений о состоянии.Служба работает нормально и дает мне следующий вывод:

{
  "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
}

Мой полный код, как указано ниже:

CountryRepository.java

@Repository
public interface CountryRepository extends JpaRepository<CountryDetails, Integer> {

    @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<CountryDetails> findAll(Pageable pageRequest);
}

CountryServiceImpl.java

@Service
public class CountryServiceImpl implements CountryService {

    @Autowired
    private CountryRepository countryRepository;

    @Override
    public Page<CountryDetails> 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 String countryName;
    private String countryCode;
    private String countryDetails;
    private String countryZone;

    @JsonManagedReference
    @OneToMany(fetch = FetchType.LAZY, mappedBy = "countryDetails")
    private List<State> 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 String stateName;
    private String countryCode;
    private String stateCode;
    private String stateDetails;
    private String 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
}

Теперь проблема

На самом деле то, что я хочу, чтобы страновая служба возвращала с минимальной информацией, как показано ниже

{
  "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
}

Итак, для достижения этого я использовал проекциикак показано ниже

CountryProjection .java

public interface CountryProjection {
    public String getCountryName();
    public String getCountryCode();
    public List<StateProjection> getStates();
}

StateProjection .java

public interface StateProjection {
    public String getStateCode();
}

CountryServiceImpl.java

@Repository
public interface CountryRepository extends JpaRepository<CountryDetails, Integer> {

    @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<CountryProjection> findAll(Pageable pageRequest);
}

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

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

Как мы можем получить сведения о минимальном состоянии, как показанониже

{
  "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
}

Может кто-нибудь, пожалуйста, помогите мне в этом

Ответы [ 4 ]

0 голосов
/ 12 июня 2018

Вы можете проверить документацию аннотации:

@ JsonIgnoreProperties ("fieldname")

Эта аннотация должна применяться к вашим классам POJO в вашем случае Страна*, State * упоминая список полей, разделенных запятыми, которые вам не нужны, чтобы быть частью ответа.

Вы можете попробовать этот подход вместо перехода на реализацию в стиле проекции.

@JsonIgnoreProperties({ "id","countryDetails","countryZone"})
public class CountryDetails

@JsonIgnoreProperties({ "id","stateName","countryCode","stateDetails","stateZone"})
public class State
0 голосов
/ 10 июня 2018

Вы можете использовать ключевое слово transient с переменной, которую вы не хотите использовать в json.

ya в противном случае используйте

@Expose String myString;
0 голосов
/ 12 июня 2018

Первая идея

ИМО, что-то не так, как ты делаешь.Я не понимаю, почему вы определяете запрос следующим образом:

@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}")

, что в основном создает проекцию с помощью select .

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

Итак, я спрашиваю: вы пытались удалить часть @Query все вместе?

Вторая идея (в глазу комментария)

Другая идея может заключаться в использовании join fetch конструкции в jpql, которая используется для перехода в спящий режим для загрузкиАссоциация охотно с запросом.

@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}"
0 голосов
/ 31 мая 2018

Попробуйте использовать JsonIgnore с полями, которые вам не нужны в возвращаемом JSON

@JsonIgnore
private String stateDetails;
...