持久化实体时设置 OneToMany 关系的 id

Setting id of OneToMany relationship when persisting entity

我有一个休眠应用程序,我想在其中保留一个所有者。

一个主人可以养很多动物

(所有者实体内部)

   @OneToMany(mappedBy = "owner")
private List<Animal> animals;

(动物实体内)

  @ManyToOne
private Owner owner;

我有一个存储库,我保留我的所有者,

   @Override
public Owner create(String name, String email, int age, 
List<Animal> animals) {
    Owner owner = new Owner(name, email, age, animals);
    for(Animal animal: animals){
        animal.setOwner(owner);
    }
    getEntityManager().persist(owner);
    return owner;
}
}

所有者被正确持久化,但动物中没有设置外键table。

我使用调试器检查了动物的所有者设置是否正确。

首先,我尝试坚持导致错误的动物

   for(Animal animal: animals){
        animal.setOwner(owner);
        getEntityManager().persist(animal)
    } //caused an error

所以我考虑使用一种级联,以确保动物将所有者 ID 放入数据库中,

@OneToMany(cascade = CascadeType.ALL)
private List<Animal> animals;

这也导致了错误

 "cause": {
  "detailMessage": "detached entity passed to persist: com.tolboll.zoo.data.entities.Animal",
  "stackTrace": [],
  "suppressedExceptions": []
},

我怎样才能使所有者正确地持久化到动物实体中?

编辑:

这是传入的JSON正文

  {
    "name": "kristoffer",
    "email": "Kristofferlocktolboll@gmail.com",
    "age": 23,
    "animals": [{
        "id": 1,
        "name": "Simba",
        "weight": 110,
        "species": {
            "id": 1,
            "name": "Lion"
        }
    }]
}

您收到该错误是因为您试图保留一个分离的实体:动物。

解决方案

在 Owner 实体中,保持原样(尽管 CascadeType.MERGE 就足够了):

@OneToMany(cascade = CascadeType.ALL)
private List<Animal> animals;

然后,在create方法中,将persist替换为merge

getEntityManager().merge(owner);

原因是 animals 列表需要合并操作。