儿童的id在cascade之后不存在坚持父母 [英] Child's id not present after cascade persisting the parent

查看:152
本文介绍了儿童的id在cascade之后不存在坚持父母的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个 User (父级)和一个 Home (子级)实体,它们遵循单向一对一-many relationship。



我的问题是,当为添加新的 Home 用户,新创建并保存的 Home 没有 id 。这是正常的吗?我需要手动坚持孩子,如果我想ID?



这些是我的实体:



<$ p $ ($ name =user)
public class User {

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name =id)
private长ID;

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

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

@NotNull
@Column(name =email)
private String email;
$ b @OneToMany(targetEntity = Home.class,fetch = FetchType.EAGER,cascade = {CascadeType.ALL},orphanRemoval = true)
@JoinColumn(name =userId,referencedColumnName = id,nullable = false)
私人列表< Home>家园;

$ b $ public public(){
}

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




$ b @实体
@Table(name =home)
public class Home实现Serializable {

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

@NotNull
@Column(name =isActive)
private布尔isActive;


public Home(){
}

}

以及更新父代码:

  Home home = HomeParser.parse(homeDTO ); 
User user = userService.findById(userId);
user.addHome(home);
userService.update(user); //代表调用getEntityManager()。merge(user);

此时我假设我有 home 有一个id,它只是在持久化到db时给出的,但它没有。



我已经尝试添加 insertable = false 到主页的标识符 @Column ,如指向这里,但它也不起作用。

解决方案

EntityManager.merge 方法实现委托给Hibernate


将给定对象的状态复制到具有
相同标识符的持久对象上。如果当前没有与会话关联的持久实例
,它将被加载。返回持久
实例。 如果给定实例未保存,则保存副本和
将其作为新的持久实例返回。给定实例不会
与会话相关联。
如果关联映射为
cascade =merge,则此操作级联到
关联实例。


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



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

I have a User (parent) and a Home (child) entities related following a unidirectional one-to-many relationship.

My problem is that, when adding a new Home to a User, the newly created and persisted Home doesn't have the id. Is this normal? Do I need to manually persist the child if I want the id?

These are my entities:

@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() {
    }

}

And the code to update the parent:

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

At this point I assumed I would have home to have the id that it's just been given when persisted to db, but it doesn't.

I already tried adding insertable = false to the Home's id's @Column, as pointed here, but it doesn't work either.

解决方案

EntityManager.merge method implementation delegates to 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".

Notice the part in bold. Basically, the merge operation will be cascaded to the Home instance you created, but Hibernate will create a copy of that instance, merge your instance into the copy, save the copy and replace your instance with the copy in the User.homes collection.

After this, User.homes collection should contain the copy of the Home instance with a properly initialized id.

这篇关于儿童的id在cascade之后不存在坚持父母的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆