Child 的 id 在级联持久化 parent 后不存在

Child's id not present after cascade persisting the parent

我有一个 User (parent) 和一个 Home (child) 个实体,遵循单向 one-to-many 关系。

我的问题是,当向 User 添加新的 Home 时,新创建和持久化的 Home 没有 id。这是正常的吗?如果我想要 id,是否需要手动保留 child?

这些是我的实体:

@Entity
@Table(name = "user")
public class User {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "id")
    private Long id;

    @NotNull
    @Column(name = "firstName")
    private String firstName;

    @NotNull
    @Column(name = "lastName")
    private String lastName;

    @NotNull
    @Column(name = "email")
    private String email;

    @OneToMany(targetEntity = Home.class, fetch = FetchType.EAGER, cascade = {CascadeType.ALL}, orphanRemoval = true)
    @JoinColumn(name = "userId", referencedColumnName = "id", nullable = false)
    private List<Home> homes;


    public User() {
    }

    public void addHome(Home home) {
        homes.add(home);
    }
}



@Entity
@Table(name = "home")
public class Home implements Serializable {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "id")
    private Long id;

    @NotNull
    @Column(name = "isActive")
    private Boolean isActive;


    public Home() {
    }

}

以及更新 parent 的代码:

Home home = HomeParser.parse(homeDTO);
User user = userService.findById(userId);
user.addHome(home);
userService.update(user); // delegate call to getEntityManager().merge(user);

在这一点上,我假设我会 home 拥有刚刚在持久化到数据库时给出的 ID,但它没有。

我已经尝试将 insertable = false 添加到家庭 ID 的 @Column,如 here 所指,但它也不起作用。

EntityManager.merge 方法实现委托给 Hibernate Session.merge:

Copy the state of the given object onto the persistent object with the same identifier. If there is no persistent instance currently associated with the session, it will be loaded. Return the persistent instance. If the given instance is unsaved, save a copy of and return it as a newly persistent instance. The given instance does not become associated with the session. This operation cascades to associated instances if the association is mapped with cascade="merge".

注意粗体部分。基本上,merge 操作将级联到您创建的 Home 实例,但 Hibernate 将创建该实例的副本,将您的实例合并到副本中,保存副本并用副本替换您的实例在 User.homes 集合中。

在此之后,User.homes 集合应包含具有正确初始化 ID 的 Home 实例的副本。