【发布时间】:2015-11-17 17:03:57
【问题描述】:
我正在使用 PlayFramework 2.3,并且我有以下课程:
MyEntity.java:
@Entity(name = "myentity")
public class MyEntity extends Model {
@Id
@GeneratedValue
public long id;
@OneToOne(cascade = CascadeType.ALL, optional = true)
@JoinColumn(name = "actual_version_id", nullable = true)
public Version actualVersion;
@OneToOne(optional = true)
@JoinColumn(name = "next_version_id", nullable = true)
public Version nextVersion;
...
}
版本.java
@Entity(name = "version")
public class Version extends Model {
@Id
@GeneratedValue
public long id;
@OneToOne
@JoinColumn(name = "entity_id", nullable = false)
public MyEntity entity;
...
}
当我想为实体创建一个新版本时,我通过分离复制它,将 id 设置为 0,然后像这样持久化:
public Version clone(){
JPA.em().detach(this);
this.id = 0;
JPA.em().persist(this);
return this;
}
如果我使用以下代码,它可以正常工作(第一个代码)
entity.nextVersion = entity.actualVersion.clone();
JPA.em().flush();
entity.actualVersion = entity.nextVersion;
entity.nextVersion = null;
JPA.em().flush();
我不是很喜欢这段代码,因为我可以像这样使用它(第二个代码)
entity.actualVersion = entity.actualVersion.clone();
JPA.em().flush();
但如果我这样做,外键不会在“实体”表中更新,我不知道为什么。谁能告诉我这两种克隆实现有什么区别?对我来说,这似乎是一些 JPA 黑魔法,但我找不到答案。
编辑:
这是一个重构的代码,使其更容易理解。我没有覆盖 Object 类中的任何函数,或任何其他函数(例如,我的 clone() 函数在原始代码中称为 newRound,带有 2 个参数)
我真的不想进行任何模型修改,比如将 CascadeType.ALL 添加到注释中,或者类似的东西,因为这是一个现在正在生产的程序,我不知道这会产生什么错误。
我只想知道为什么第一个代码会更新实体中的外键 (actual_version_id) 而第二个不会。我认为它必须与实际版本变量中的 CascadeType.ALL 注释参数有关。
【问题讨论】:
-
你在persist期间设置了级联对象写入吗?
-
我不太明白你的问题。设置级联对象写入是什么意思?
-
我确信它依赖于 JPA 提供者的实现,但是......我会说,在身份由提供者管理的实体 (
@GeneratedValue) 上自己操作键值是一种犯规。 -
@aBnormaLz 试试
@OneToOne(cascade=CascadeType.ALL)。 -
实际上用 ids 操作不是犯规stackoverflow.com/questions/11625096/cloning-jpa-entity@Tassos Bassoukos 你的意思是用它来注释 MyEntity 属性吗?我不知道这是否会给代码带来任何其他问题(这是我当时支持的一个大型在线项目)
标签: java jpa playframework-2.3