为什么JPA不更新OneToOne关系上的外键?

时间:2015-11-17 17:03:58

标签: 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_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.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添加到注释或类似的东西,因为这是一个现在生产的程序,我不知道会产生什么错误。 / p>

我只想知道为什么第一个代码更新实体中的外键(actual_version_id)而第二个代码没有。我认为必须在actualVersion变量上使用CascadeType.ALL注释参数。

1 个答案:

答案 0 :(得分:0)

在JPA设置中对clone()非常小心; JPA环境通常会将跟踪属性添加到类的字节码中,并且可能会混淆。相反,覆盖默认的clone()以创建实际对象,并逐个手动复制所有属性。