Java 为什么';JPA是否更新OneTONE关系上的外键?
我使用的是PlayFramework 2.3,我有以下几个类: MyEntity.java:Java 为什么';JPA是否更新OneTONE关系上的外键?,java,jpa,playframework-2.3,Java,Jpa,Playframework 2.3,我使用的是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_
@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;
...
}
当我想为实体创建新版本时,我通过分离复制它,将id设置为0,并按如下方式保持:
public Version clone(){
JPA.em().detach(this);
this.id = 0;
JPA.em().persist(this);
return this;
}
如果我使用以下代码,它将正常工作(第一个代码)
我真的不喜欢这个代码,因为我可以像这样使用它(第二个代码)
但是如果我这样做,外键不会在“entity”表中更新,我不知道为什么。有人能告诉我这两种克隆的不同之处吗?对我来说,这似乎是一些JPA的黑魔法,但我找不到答案
编辑:
这是一段经过重构的代码,使其更易于理解。我没有重写对象类中的任何函数或任何其他函数(例如,我的clone()函数在原始代码中使用2个参数调用newRound)
我真的不想做任何模型修改,比如在注释中添加CascadeType.ALL之类的,因为这是一个正在生产的程序,我不知道会产生什么bug
我只想知道为什么第一个代码会更新实体中的外键(实际版本id),而第二个代码不会。我认为它必须是某个CascadeType.ALL注释参数在actualVersion变量处 在JPA设置中使用
clone()
时要非常小心;JPA环境通常会将跟踪属性添加到类的字节码中,这可能会引起混淆。相反,请覆盖默认的clone()
,以创建实际对象并手动逐个复制所有属性。是否在“持久化”过程中设置了级联对象写入?我不太理解您的问题。设置级联对象写入是什么意思?我肯定它依赖于JPA提供程序实现,但是。。。我想说的是,在一个身份由提供者管理的实体上自己操纵键值(@GeneratedValue
)是一种违反规则的行为。@normalz try@OneToOne(cascade=CascadeType.ALL)
。实际上,用ids操纵并不是违反规则@Tassos Bassoukos你的意思是用它来注释MyEntity属性吗?我不知道这是否会在代码中产生任何其他问题(这是我当时支持的一个大型在线项目)
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();