我正在使用hibernate实体管理器(4.2.16)。 在添加新子项后,我在合并现有实体时遇到了问题。我想获取新创建的子项的id,但未设置id。 这是我的模特:
@Entity
@Table(name = "PARENT")
@GenericGenerator(name = "gen_identifier", strategy = "sequence", parameters = {
@Parameter(name = "sequence", value = "SQ_PARENT")
})
public class Parent {
@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "gen_identifier")
private Long id;
@OneToMany(cascade = CascadeType.ALL, orphanRemoval = true, mappedBy = "parent")
private Set<Child> children;
}
@Entity
@Table(name = "CHILD")
@GenericGenerator(name = "gen_identifier", strategy = "sequence", parameters = {
@Parameter(name = "sequence", value = "SQ_CHILD")
})
public class Child {
@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "gen_identifier")
private Long id;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "PARENT_ID")
private Parent parent;
}
创建父级的代码(事务1):
public Long saveParent() {
Parent parent = new Parent();
entityManager.persist(parent);
System.out.println("saveParent : parent.id = " + parent.getId());
return parent.getId();
}
添加子代码(事务2)
public void addChild(Parent parent) {
Child child = new Child();
child.setParent(parent);
parent.getChildren().add(child);
entityManager.merge(parent);
System.out.println("addChild : parent.id = " + parent.getId());
// The following give me a null id
System.out.println("addChild : child.id = " + parent.getChildren().iterator().next().getId());
System.out.println("addChild : child.id = " + child.getId());
}
执行代码时,我希望子id不为null。这是我得到的输出:
saveParent : parent.id = 1000
addChild : parent.id = 1000
addChild : child.id = null
addChild : child.id = null
答案 0 :(得分:1)
合并始终返回一个新的非实体化实体,您应该将其用作您的实体操作。调用合并后发生的所有更改仅反映在从merge返回的实体中。为了解决您的问题,您需要更改你编码如下
public Parent addChild(Parent parent) {
Child child = new Child();
child.setParent(parent);
parent.getChildren().add(child);
parent=entityManager.merge(parent);
System.out.println("addChild : parent.id = " + parent.getId());
// The following give me a null id
System.out.println("addChild : child.id = " + parent.getChildren().iterator().next().getId());
System.out.println("addChild : child.id = " + child.getId());'
return parent;
}
您还应该从此方法返回父级,以便调用此方法的任何代码都应使用新生成的父级,而不是使用旧的,不会通过合并进行任何更改。
要阅读有关merge()的更多信息,请访问以下链接
http://blog.xebia.com/jpa-implementation-patterns-saving-detached-entities/