Json 外键在一对多关系中始终为空-Spring引导数据与JPA

Json 外键在一对多关系中始终为空-Spring引导数据与JPA,json,rest,spring-boot,spring-data-jpa,one-to-many,Json,Rest,Spring Boot,Spring Data Jpa,One To Many,我有两个实体类Country和Language具有双向一对多关系 以下是实体类: @Entity @Table(name = "COUNTRY") public class Country { @Id @GeneratedValue @Column(name = "COUNTRY_ID") private Long id; @Column(name = "COUNTRY_NAME") private String name; @Col

我有两个实体类
Country
Language
具有双向一对多关系

以下是实体类:

@Entity
@Table(name = "COUNTRY")
public class Country {

    @Id
    @GeneratedValue
    @Column(name = "COUNTRY_ID")
    private Long id;

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

    @Column(name = "COUNTRY_CODE")
    private String code;

    @JacksonXmlElementWrapper(localName = "languages")
    @JacksonXmlProperty(localName = "languages")
    @OneToMany(mappedBy = "country", fetch = FetchType.EAGER, cascade = CascadeType.ALL)
    List<Language> languages;
    // getters and setters
}
下面是我的Rest控制器:

@RestController
@RequestMapping("/countries")
public class CountryRestController {

    private final ICountryRepository iCountryRepository;

    @Autowired
    public CountryRestController(ICountryRepository iCountryRepository) {
        this.iCountryRepository = iCountryRepository;
    }

    @PostMapping("/country")
    public ResponseEntity<?> postCountryDetails(@RequestBody Country country) {
        Country savedCountry = this.iCountryRepository.save(country);

        URI location = ServletUriComponentsBuilder.fromCurrentRequest().path("/{id}")
                .buildAndExpand(savedCountry.getId()).toUri();
        return ResponseEntity.created(location).build();
    }

 //other methods

}
问题是语言(子)外键始终为空,但会插入其他属性。我在
Language
类的属性
Country-Country
上使用了
@JsonIgnore
,因为它导致了请求大小问题,因为我有另一个API获取国家及其语言的数据


请导游

您可以这样做:

Country newCountry = new Country(country.getName());

ArrayList < Language > langList = new ArrayList<>();

for (Language lang : country.getLanguages()) {
     langList.add( new Language(language.getName(), newCountry ) ) ;
}

newCountry.setLanguages( langList );

iCountryRepository.save(newCountry);

你也可以这样做。 在这里,它不会创建新对象。在解析的同一对象中,它在语言对象中创建关系

@PostMapping("/country")
public Country postCountryDetails(@RequestBody Country country) {

    if( country.getLanguages().size() > 0 )
    {
        country.getLanguages().stream().forEach( countryItem -> {
            countryItem.setCountry( country );
        } );
    }
    return country;
}

国家
类中的
语言
的setter更新为以下内容:

 public void setLanguages(List<Language> languages) {
        this.languages = languages;
        languages.forEach(entity -> entity.setCountry(this));
    }
公共语言(列表语言){
这个。语言=语言;
languages.forEach(entity->entity.setCountry(this));
}

谢谢。这对我有用。你能给我解释一下你的答案吗?为什么它不按我的方式工作?我认为这是因为输入对象(国家)有child(语言),child不知道Hibernate上下文中的父对象是谁。因此,您需要创建新的父项和子项,并显式设置子项的父项。这就是为什么在最初的方式中,它插入到两个表中,尽管没有外键。。但当您告诉上下文(使用constructor)指向哪个父对象时,它首先在子表中插入父对象并映射外键。如何仅使用域类实现这一点?不创建两次对象?您的java版本是否低于8?
public Country() {}

public Country(String name) {this.name = name } 
@PostMapping("/country")
public Country postCountryDetails(@RequestBody Country country) {

    if( country.getLanguages().size() > 0 )
    {
        country.getLanguages().stream().forEach( countryItem -> {
            countryItem.setCountry( country );
        } );
    }
    return country;
}
 public void setLanguages(List<Language> languages) {
        this.languages = languages;
        languages.forEach(entity -> entity.setCountry(this));
    }