我在两个班级之间有一个经典的一对多亲子关系。在初始创建时,我创建一个父ID,其中ID = 0,ID为0的子项。然后,在子项中添加对父项的引用,然后将子项添加到父项列表中。我使用下面的代码进行保存,父和子都使用新ID保存在数据库中,并且生成的父和子bean都在bean中指定了ID。
当我向一个现有的,分离的bean 添加一个额外的子bean时,我创建新的子bean,设置ID = 0,并将父作为引用,然后将其添加到父级名单。然后我运行下面列出的编辑代码,数据库显示新子项已使用新ID保存到数据库,但新子bean未显示新ID ...
在为这种关系添加新孩子时,我应该做些什么?
父类:
class parent
{
@GeneratedValue( strategy = GenerationType.IDENTITY )
private Integer id;
@OneToMany( mappedBy = "parent", cascade = CascadeType.ALL, fetch = FetchType.EAGER )
private List<Child> childList;
}
儿童班:
class child
{
@GeneratedValue( strategy = GenerationType.IDENTITY )
private Integer id;
@ManyToOne( fetch = FetchType.EAGER, cascade = CascadeType.ALL )
@JoinColumn( name = "ID_PARENT", nullable = false )
private Parent parent;
}
保存初始代码:
Parent parent = new Parent();
parent.setID( 0 );
Child child = new Child( );
child.setID( 0 );
child.setParent( parent );
List<Child> childList = new List<>();
childList.add( child );
parent.addChildList( childlist );
em.persist( parent );
em.flush();
parent.getID(); // will display ID in db
parent.getChildList(0).getID(); // will have ID from database
编辑代码:
addChild( Parent detachedParent )
{
Child child = new Child( );
child.setID( 0 );
child.setParent( detachedParent );
detachedParent.getChildList().add( child );
em.merge( detachedParent );
em.flush();
parent.getID(); // will display ID in db
parent.getChildList( 0 ).getID(); // will have ID from database
parent.getChildList( 1 ).getID(); // will be 0, but database has new ID
}
答案 0 :(得分:1)
使用em.persist()
时,它会修改您作为参数传递的对象,但是当您使用em.merge()
时,它会从数据库加载一个新副本,并将您传递的对象的更改合并为参数然后返回合并的对象。在您的情况下,您检查传递给em.merge()
的对象(未被调用修改),您必须将merge的返回值分配给变量,然后从该父级访问已添加的子项。
addChild( Parent detachedParent )
{
Child child = new Child( );
child.setID( 0 );
child.setParent( detachedParent );
detachedParent.getChildList().add( child );
parent = em.merge( detachedParent ); // assign merged copy to parent
em.flush();
parent.getID(); // will display ID in db
parent.getChildList( 0 ).getID(); // will have ID from database
parent.getChildList( 1 ).getID(); // should display same id as the one from DB
}