【问题标题】:Why doesn't JPA update the foreign key on a OneToOne relation?为什么 JPA 不更新 OneToOne 关系的外键?
【发布时间】: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


【解决方案1】:

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

【讨论】:

    猜你喜欢
    • 2020-07-08
    • 2021-08-16
    • 1970-01-01
    • 2016-05-26
    • 2023-03-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-10-10
    相关资源
    最近更新 更多