SJu*_*n76 49
使用EntityManager.detach.它使bean不再链接到EntityManager.然后将Id设置为新Id(如果是自动则设置为null),更改所需的字段并保持不变.
sch*_*pel 14
使用EclipseLink时,您可以使用非常方便的CopyGroup-Feature:
http://wiki.eclipse.org/EclipseLink/Examples/JPA/AttributeGroup#CopyGroup
一个很大的优点是,没有太多的摆弄,它也恰当地克隆了私有的关系.
这是我的代码,使用私人拥有的@ OneToMany关系克隆播放列表只需几行:
public Playlist cloneEntity( EntityManager em ) {
CopyGroup group = new CopyGroup();
group.setShouldResetPrimaryKey( true );
Playlist copy = (Playlist)em.unwrap( JpaEntityManager.class ).copy( this, group );
return copy;
}
Run Code Online (Sandbox Code Playgroud)
确保使用persist()保存此新对象,merge()不起作用.
最好使用复制构造函数并准确控制需要克隆的属性。
所以,如果你有一个Post这样的实体:
@Entity(name = "Post")
@Table(name = "post")
public class Post {
@Id
@GeneratedValue
private Long id;
private String title;
@OneToMany(
mappedBy = "post",
cascade = CascadeType.ALL,
orphanRemoval = true
)
private List<PostComment> comments = new ArrayList<>();
@OneToOne(
mappedBy = "post",
cascade = CascadeType.ALL,
orphanRemoval = true,
fetch = FetchType.LAZY
)
private PostDetails details;
@ManyToMany
@JoinTable(
name = "post_tag",
joinColumns = @JoinColumn(
name = "post_id"
),
inverseJoinColumns = @JoinColumn(
name = "tag_id"
)
)
private Set<Tag> tags = new HashSet<>();
//Getters and setters omitted for brevity
public void addComment(
PostComment comment) {
comments.add(comment);
comment.setPost(this);
}
public void addDetails(
PostDetails details) {
this.details = details;
details.setPost(this);
}
public void removeDetails() {
this.details.setPost(null);
this.details = null;
}
}
Run Code Online (Sandbox Code Playgroud)
comments在复制 aPost并将其用作新的模板时克隆是没有意义的:
Post post = entityManager.createQuery(
"select p " +
"from Post p " +
"join fetch p.details " +
"join fetch p.tags " +
"where p.title = :title", Post.class)
.setParameter(
"title",
"High-Performance Java Persistence, 1st edition"
)
.getSingleResult();
Post postClone = new Post(post);
postClone.setTitle(
postClone.getTitle().replace("1st", "2nd")
);
entityManager.persist(postClone);
Run Code Online (Sandbox Code Playgroud)
您需要添加到Post实体的是copy constructor:
/**
* Needed by Hibernate when hydrating the entity
* from the JDBC ResultSet
*/
private Post() {}
public Post(Post post) {
this.title = post.title;
addDetails(
new PostDetails(post.details)
);
tags.addAll(post.getTags());
}
Run Code Online (Sandbox Code Playgroud)
这是解决实体克隆/复制问题的最佳方法。任何试图使此过程完全自动化的其他方法都忽略了并非所有属性都值得复制这一点。
| 归档时间: |
|
| 查看次数: |
38156 次 |
| 最近记录: |