既に永続化されているエンティティがあり、それを新しく生成された親エンティティ (まだ永続化されていません) に追加したいと考えています。親を永続化しようとすると、「永続化するために渡された切り離されたエンティティ: model.Child」というエラーが表示されます。「entityManager.persist()」ではなく、子に対して「entityManager.merge()」を呼び出す必要があると思います。しかし、私は永続化を明示的に呼び出しません。これは、「cascade = CascadeType.ALL」アノテーションによって処理されます。エンティティが既に存在する場合、ここでマージを行うように hibernate に何らかの方法で指示できますか?
ちなみに、最初に親を永続化してから、子を追加してから親を再度永続化すると、機能します(ただし、アプリケーションロジックがはるかに複雑になります)。
ここに私のコード:
public class App
{
@Test
public void test()
{
// I have a child object (in the real app
//this is a user object and already persisted
Child child = new Child();
HibernateHelper.persist(child);
Parent parent = new Parent();
parent.addChildren(child);
// throws the exception "detached entity passed to persist: model.Child"
HibernateHelper.persist(parent);
Parent newParent = HibernateHelper.find(Parent.class, parent.getId());
assertEquals(1, newParent.getChildren().size());
}
}
私の「子」エンティティ:
@Entity
@Table(name = "child")
public class Child {
public Child(){}
private Long id;
@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
private Parent parent;
@ManyToOne
@JoinColumn
public Parent getParent() {
return parent;
}
public void setParent(Parent parent) {
this.parent = parent;
}
}
私の「親」エンティティ:
@Entity
@Table(name="parent")
public class Parent {
public Parent(){}
private Long id;
@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
private Set<Child> children = new HashSet<Child>();
@OneToMany(mappedBy = "parent", cascade = CascadeType.ALL)
public Set<Child> getChildren() {
return children;
}
public void setChildren(Set<Child> children) {
this.children = children;
}
public void addChildren(Child child){
children.add(child);
child.setParent(this);
}
}
persist ヘルパー メソッド (子でも同じように見えます)
public static void persist(Parent entity){
EntityManager entityManager = null;
try {
entityManager = beginTransaction();
if(entity.getId()!=null){
entityManager.merge(entity);
}else{
entityManager.persist(entity);
}
entityManager.getTransaction().commit();
} catch (Exception e) {
System.out.println(e);
return;
}finally{
if(entityManager != null)
entityManager.close();
}
}