jpa 不能保存一对一关系的父子

djmepvbi  于 2023-10-19  发布在  其他
关注(0)|答案(1)|浏览(128)

想象一下,你有下一个实体:

@Entity(name = "software")
@Table(name = "software")
public class SoftwareEntity {

   @Id
   UUID id;
   String name;
   String description;
   // other properties
 
    @OneToOne(cascade = CascadeType.ALL)
    @JoinTable(name = "current_version",
                    joinColumns = {@JoinColumn(name = "sowtware_id")},
                    inverseJoinColumns = {@JoinColumn(name = "version_id")})

   VersionEntity currentVersion;
}

@Entity(name = "version")
@Table(name = "version")
public class VersionEntity {

   @Id
   @Column("version_id")
   UUID versionId;

   @Column("software_id")
   UUID softwareId;

   // other properties
}

在Version实体中,我不喜欢持有整个父SoftwareEntity。我只需要识别码。
在数据库级别,我有下一个表:

CREATE TABLE software {
  id       UUID PRIMARY KEY,
  name                    STRING,
  description             STRING
}

CREATE TABLE version {
   version_id UUID PRIMARY KEY,
   software_id UUID NOTNULL,

    FOREIGN KEY (software_id) REFERENCES software (id)
}

CREATE TABLE current_version {
     software_id       UUID NOT NULL UNIQUE,
     version_id        UUID NOT NULL,

     PRIMARY KEY (software_id, version_id),

     FOREIGN KEY (software_id) REFERENCES software (id),
     FOREIGN KEY (version_id) REFERENCES version (version_id)
}

我的典型用例如下:

var software = createNewSoftware();
var version = createNewVersion(software.id());
software.setCurrentVersion(version);
...
softwareJpaRepository.save(software); // fails here

当我这样做时,JPA将首先保存版本,但失败了,因为新的软件实体还没有保存,版本表中有外键约束。(org.hibernate.exception.ConstraintViolationException)
如果我在软件和版本之间的一对一关系中禁用cascade选项,JPA将首先寻求保存版本,并且也会失败,因为该版本尚未保存。(javax.persistence.EntityNotFoundException)
有没有人知道如何修复它,保持实体和表的相同/相似结构?

e0uiprwp

e0uiprwp1#

您可以直接在代码本身显式设置 * 软件实体id* 和 * 版本实体id*:

@Id
private UUID id = UUID.randomUUID();

并且,您可以通过以下方式保存软件实体:

// Software entity id already set
SoftwareEntity softwareEntity = new SoftwareEntity();
       
//version entity id already set
VersionEntity versionEntity = new VersionEntity();
//foreign key set
versionEntity.setSoftwareId(softwareEntity.getId());

softwareEntity.setCurrentVersion(versionEntity);
softwareEntityRepository.save(softwareEntity);

相关问题