Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/67.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java Spring投影不返回状态详细信息_Java_Mysql_Hibernate_Spring Data Jpa_Spring Projections - Fatal编程技术网

Java Spring投影不返回状态详细信息

Java Spring投影不返回状态详细信息,java,mysql,hibernate,spring-data-jpa,spring-projections,Java,Mysql,Hibernate,Spring Data Jpa,Spring Projections,我有一个国家和州表,我已经将其与Spring数据JPA集成。我已经在my CountryServiceImpl中创建了一个函数公共页面getAllCountryDetails,用于获取所有国家和相应州的详细信息。该服务运行良好,并为我提供以下输出: { "content": [ { "id": 123, "countryName": "USA", "countryCode": "USA", "countryDetails": "XXXX

我有一个国家和州表,我已经将其与Spring数据JPA集成。我已经在my CountryServiceImpl中创建了一个函数
公共页面getAllCountryDetails
,用于获取所有国家和相应州的详细信息。该服务运行良好,并为我提供以下输出:

{
  "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);
}
@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));
    }
}
@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
}
@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
}
public interface CountryProjection {
    public String getCountryName();
    public String getCountryCode();
    public List<StateProjection> getStates();
}
public interface StateProjection {
    public String getStateCode();
}
@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",
      "states": [
        {
          "stateCode": "WAS"
        },
        {
          "stateCode": "SOS"
        }
      ]
    }
  ],
  "last": false,
  "totalPages": 28,
  "totalElements": 326,
  "size": 12,
  "number": 0,
  "sort": null,
  "numberOfElements": 12,
  "first": true
}
{
  "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
}
为了实现这一点,我使用了如下所示的预测

{
  "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
}
{
  "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
}
CountryProjection.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);
}
@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));
    }
}
@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
}
@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
}
public interface CountryProjection {
    public String getCountryName();
    public String getCountryCode();
    public List<StateProjection> getStates();
}
public interface StateProjection {
    public String getStateCode();
}
@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);
}
CountryServiceImpl.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);
}
@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));
    }
}
@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
}
@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
}
public interface CountryProjection {
    public String getCountryName();
    public String getCountryCode();
    public List<StateProjection> getStates();
}
public interface StateProjection {
    public String getStateCode();
}
@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",
      "states": [
        {
          "stateCode": "WAS"
        },
        {
          "stateCode": "SOS"
        }
      ]
    }
  ],
  "last": false,
  "totalPages": 28,
  "totalElements": 326,
  "size": 12,
  "number": 0,
  "sort": null,
  "numberOfElements": 12,
  "first": true
}
{
  "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
}

有人能帮我一下吗

试着用JsonIgnore处理返回JSON中不需要的字段

@JsonIgnore
private String stateDetails;

您可以将
transient
关键字与json中不需要的变量一起使用

否则你会使用

@Expose String myString;
第一个想法 在我看来,你做事的方式有些不对劲。我不明白您为什么直接这样定义查询:

@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}")
基本上就是通过选择创建投影

另一方面,您正在使用which再次进行投影,但是通过公开要投影的属性的getter。就我所见,您通过接口很好地定义了层次结构,这应该是一种有效的方法

所以我想问的是,您是否尝试过一起删除
@Query
部分

第二个想法(在评论中) 另一个想法是使用
jpql
中的
join-fetch
,它用来告诉hibernate使用查询急切地加载关联

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

您可以查看注释的文档:

@JsonIgnoreProperties(“字段名”)

此注释需要应用于案例国家*、州*中的POJO类,其中提到了以逗号分隔的字段列表,您不需要成为响应的一部分

您可以尝试这种方法,而不是更改为投影样式的实现

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

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

您可以让您的
CountryService
返回一个DTO,而不是只包含所需字段的实体

服务
@服务
公共类CountryServiceImpl实现CountryService{
@自动连线
私有国家知识库国家知识库;
@凌驾
公共页面getAllCountryDetails(最终整型页面,最终整型大小){
return countryRepository.findAll(新页面请求(页面,大小))
.map(c->{
CountryDetailsTo dto=新的CountryDetailsTo();
dto.setCountryCode(c.getCountryCode());
dto.setCountryName(c.getCountryName());
dto.setStates(c.getStates().stream().map(s->{
StateDto StateDto=新StateDto();
stateDto.setStateCode(s.getStateCode());
返回stateDto;
}).collect(Collectors.toSet());
返回dto;
});
}
}
DTO
公共类CountryDetailsTo{
私有字符串countryName;
私有字符串国家代码;
私有国家;
}
public类StateDto{
私有字符串状态码;
}

为什么接口中的getter使用私有修饰符?@Turo很抱歉……它是公共的您没有在CountryProjection中使用StateProjection,这些接口不应该扩展为可序列化吗?@Turo我不明白……你能给我一个exampe@Turo你的意思是我使用的是
State
而不是
StateProjection
,只有
stateCode
。甚至我也尝试过,但是状态详细信息没有打印出来,我不能使用
@JsonIgnore
,因为我需要其他服务中的这些详细信息….在@Query中,您不是从状态表中查询状态代码,请尝试连接到状态table@manishsingh....Thanks你能给我举个例子吗谢谢你的回复。。。我应该将json忽略注释应用到CountryDetails和State model类别上……实际上,如果我这样做,那么它将始终忽略这些字段……我确实需要忽略值的其他服务。您是对的,它们在返回响应时将被忽略。与您的情况一样,如果您必须处理相同的对象结构,以便在不同的API调用中表现出不同的行为,那么您必须使用自定义映射器实用程序来检查请求调用并派生响应中包含的必要属性。寻找下面的项目与这样的定制。谢谢你的回复。。。。实际上,我不能删除@Query,因为我有一个搜索查询也要针对多个字段进行搜索(我在当前的SO示例中没有显示)....@AlexMan如果您没有将问题呈现出来,您如何期望一个可行的解决方案?我尝试了…并得到了一个异常
,原因是:org.hibernate.QueryException:query指定的联接获取,但获取关联的所有者不在选择列表中
Ok,似乎该关联已被其他内容配置为“渴望”。你还可以尝试两件事:1。仅从查询中删除
fetch
,或2:完全删除join子句,但添加
country。states
到select。您的意思是这样的
@Query(value=“select country.countryName作为countryName,country.countryCode作为countryCode,countryStates来自country.states countryStates按国家分组。countryId按?{pageable}”排序)