POST后返回具有@ManyToOne关系的已保存实体

时间:2019-04-03 09:37:47

标签: java spring spring-boot

我有一个名为Person的实体的Spring Boot应用程序,该实体具有@ManyToOne的关系:

@Entity
public class Person {
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private long id;

    private String firstName;
    private String lastName;

    @ManyToOne
    private Country country;
    // ...
}

PersonController用于允许GET现有人员和POST新人员:

@RestController
public class PersonController {

    private final PersonRepository personRepository;

    @Autowired
    public PersonController(final PersonRepository personRepository) {
        this.personRepository = personRepository;
    }

    @GetMapping("/person/{personId}")
    public Person getPerson(@PathVariable long personId) {
        return personRepository.findById(personId).get();
    }

    @PostMapping("/person_save_and_return_by_id")
    public Person personSaveAndReturnById(@RequestBody Person person) {
        Person savedPerson = personRepository.save(person);
        // the payload sent by the client does not necessarily include all
        // properties of the Country class, it might contain just the id.
        // Therefore, we fetch the person from the database, so that all
        // necessary JOIN operations are made and no properties are set to null.
        Person samePerson = personRepository.findById(savedPerson.getId()).get();
        return samePerson;
    }
}

我想POST个新朋友,而不必完整描述现有的Country,我只想表示其ID:

curl -i -X POST -H "Content-Type:application/json" -d '{"firstName": "Frodo", "lastName": "Baggins", "country": {"id": 1}}' http://localhost:8080/person_save_and_return_by_id

不幸的是,返回的实体具有除ID之外的所有国家/地区属性,均设置为null:

{
   "firstName" : "Frodo",
   "id" : 4,
   "lastName" : "Baggins",
   "country" : {
      "id" : 1,
      "description" : null,
      "countryCodeIso" : null
   }
}

POST请求将所有内容插入数据库。例如,如果我GET我先前发布的对象:

curl -i  http://localhost:8080/person/4 

返回的json看起来应该完全一样:

{
   "lastName" : "Baggins",
   "firstName" : "Frodo",
   "country" : {
      "id" : 1,
      "countryCodeIso" : "FR",
      "description" : "France"
   },
   "id" : 4
}

但这对我没有帮助,因为我需要使用创建新Country的相同方法访问Person实例。

我的问题是,当完全相同的人在@PostMapping中没有这些空值时,为什么新建的人在@GetMapping方法中有一个将某些属性设置为null的国家/地区之后吗如何在@PostMapping期间正确访问此人所在的国家/地区,而无需采取变通办法,例如通过其ID明确获取该国家/地区?

该代码也可以在github上使用。它使用了h2database,但是hibernate和postgresql存在相同的问题。请注意,在启动过程中插入了两个国家/地区,因此当国家/地区ID设置为1或2时不会抛出任何违反外键的情况。

2 个答案:

答案 0 :(得分:0)

您尝试添加

@ManyToOne(cascade = CascadeType.MERGE)

答案 1 :(得分:0)

如果您在有效负载中提供了country_id,则只能从存储库中获取国家/地区。然后将整个国家/地区对象设置为Person并保存person。