Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
121 views
in Technique[技术] by (71.8m points)

java - Detached entity passed to persist when mapping existing child entity to new parent entity

I have two entity as below.

// Parent entity
class Parent {
 @OneToMany(mappedBy = "parent", orphanRemove=true, cascade=CascadeType.ALL)
 Set<Child> children;
}

// Child entity
class Child {
  @ManyToOne(cascade={CascadeType.MERGE, CascadeType.PERSIST})
  Parent parent;
}

I already have one Parent object which has two Child object and I want to move one Child object from current Parent to new Parent.

@Transactional
public void mapChildToNewParent() {
    // Get existing child and remove it from existing parent
    Parent existingParent = parentRepo.findById(1L);
    Child existingChild = existingParent.getChildren().iterator().next();
    existingParent.remove(existingChild);

    // Create new parent and add existingChild in it
    Parent newParent = new Parent();
    Set<Child> childrens = new HashSet<Child>();
    childrens.add(existingChild);
    newParent.setChildren(childrens)

    // Save modified parent entities
    parentRepo.save(existingParent);
    parentRepo.save(newParent);
}

Now when I do this, save method throws detached entity passed to persist: Child

question from:https://stackoverflow.com/questions/65939410/detached-entity-passed-to-persist-when-mapping-existing-child-entity-to-new-pare

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

You're missing a fundamental step in your code: You need to update the association's owning side. Missing that can cause these kinds of exceptions or prevent Hibernate from performing any update on the database.

And you might want to double-check your cascade operations. More about that at the end of this post.

Disclaimer: I wasn't able to reproduce the error message in my example project. Instead of the error, Hibernate quietly removed the child record from the database. But that might be a detail that depends on the Hibernate version and/or the surrounding code.

Managing bidirectional associations

Let's start with the most important part: You modeled a bidirectional association. When you use it in your business code, you always need to update both sides.

If you want to dive deeper into association mappings, I recommend studying my best association mapping articles.

In your example, the call of the child.setParent(newParent) method is missing:

@Transactional
public void mapChildToNewParent() {
    // Get existing child and remove it from existing parent
    Parent existingParent = parentRepo.findById(1L);
    Child existingChild = existingParent.getChildren().iterator().next();
    existingParent.remove(existingChild);

    // Create new parent and add existingChild in it
    Parent newParent = new Parent();
    Set<Child> childrens = new HashSet<Child>();
    childrens.add(existingChild);
    newParent.setChildren(childrens)

    child.setParent(existingChild);

    // Save modified parent entities
    parentRepo.save(existingParent);
    parentRepo.save(newParent);
}

Using cascading and orphanRemoval

You're using cascading and orphanRemoval in your mappings. These should only be used for pure parent-child associations in which the child depends on the parent. In these cases, having a cascade definition on both ends of the association is uncommon. You should double-check if you need the cascade definition on the Child.parent attribute and if it provides the expected results.

If your parent has many children, cascading a removal operation might cause performance issues.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...