我使用PlayFramework 2.3和我有以下类:为什么JPA不更新OneToOne关系上的外键?
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;
...
}
Version.java
@Entity(name = "version")
public class Version extends Model {
@Id
@GeneratedValue
public long id;
@OneToOne
@JoinColumn(name = "entity_id", nullable = false)
public MyEntity entity;
...
}
,当我想,以便为新版本实体,我通过detach复制它,将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),而第二个代码没有。我认为它必须与actualVersion变量中的CascadeType.ALL注释参数一致。
您是否在持续期间设置了级联对象写入? –
我真的不明白你的问题。通过设置级联对象写什么意思? – aBnormaLz
我确定它是JPA提供程序实现的依赖,但是......我想说的是,在身份为提供程序管理的实体('@ GeneratedValue')上操纵密钥值是一方的犯规。 – scottb