Cod*_*kie 27 java hibernate jpa
我正在使用带有一些嵌套表的单列pk的关系数据库.我需要在项目中添加简单的归档.归档仅在应用程序到达特定状态时发生,因此我希望将现有的hibernate对象复制到新实例中,新实例将使用新ID保存,同时保留现有对象.我似乎无法弄清楚如何将现有对象复制到新实例而无需手动设置每个新的实例字段.有人知道这样做的简单方法吗?
Gab*_*ica 40
只需检索对象,将其分离,将id设置为null并保持它.
MyEntity clone = entityManager.find(MyEntity.class, ID);
entityManager.detach(clone);
clone.setId(null);
entityManager.persist(clone);
Run Code Online (Sandbox Code Playgroud)
如果您的对象具有oneToMany关系,则必须为所有子项重复操作,但设置父对象id(在persist
调用之后生成)而不是null.
当然,您必须删除CASCADE persist
OneToMany关系中的任何关系,否则您的持久性将在DB或fk约束失败中创建所有子项的重复项.
detach
在克隆实体时,按照其他人的建议使用或深度克隆并不是要走的路。如果您尝试使此过程完全自动化,您将错过并非所有属性都值得复制这一点。
因此,最好使用复制构造函数并准确控制需要克隆的属性。
所以,如果你有一个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
实体的是一个复制构造函数:
/**
* 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)
因此,复制构造函数是解决实体克隆/复制问题的最佳方法。
我也在使用Hibernate,我得到了同样的要求.我遵循的是实施Cloneable
.下面是如何执行此操作的代码示例.
class Person implements Cloneable {
private String firstName;
private String lastName;
public Object clone() {
Person obj = new Person();
obj.setFirstName(this.firstName);
obj.setLastName(this.lastName);
return obj;
}
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
}
Run Code Online (Sandbox Code Playgroud)
或者你可以去基于反射的解决方案,但我不会建议.查看此网站了解更多详情.
归档时间: |
|
查看次数: |
53210 次 |
最近记录: |