【问题标题】:JPA entity relation in table which sharing same key as foreign and primary?表中的JPA实体关系与外部和主要共享相同的键?
【发布时间】:2021-03-16 08:51:00
【问题描述】:

现在,我有两张桌子。

第一个表(对象表):

RefNo (PK) --> auto ascending
Type
Status
...

第二个表(对象详细表):

RefNo (PK) --> FK reference from 1st Table
PolicyNo
DepNo
...

对象的实体。

  @Id
  @GeneratedValue(strategy = GenerationType.IDENTITY)
  private long refnno;

  @OneToOne(mappedBy = "obejctTwo")
  private ObjectDetail objectDetail;

  private String type;

  private String status;

ObjectDetail 的实体

  @Id
  private long refnno;

  @OneToOne
  @JoinColumn(name = "refnno")
  @MapsId
  private Object object;

  private String policyNo;

  private String depNo;

如何使用 jpaRepository for Object 保存对象,其中在对象 JSON 中包含 ObjectDetail,但不知道由 db 自动生成的 refno(PK)。

{
    "objectDetail": {
        "policyNo": "12345678",
        "depNo": "ABC"
    },
    "type": "new",
    "status": "pending"
}

【问题讨论】:

  • 你可以使用@OneToOne(cascade = CascadeType.ALL)
  • 我试过这个,但还是不行。错误消息:INSERT 语句与 FOREIGN KEY 约束“OBJECTDETAIL_PK”冲突。

标签: database jpa spring-data-jpa entity one-to-one


【解决方案1】:

不能在Object类中用注解@OneToOne(cascade = CascadeType.PERSIST)级联保存吗?

然后,我将使用可用的详细信息创建两个对象,设置关系并保存类 Object

object.setObjectDetail(objectDetail);
objectdetail.setObject(object);
repository.save(object);

object 的密钥将自动设置,objectDetail 将从object 获取密钥。

编辑:实体示例

我对代码不起作用感到有点惊讶。因此,我为自己实现了这个。它与 Spring Boot 版本 2.3.2.RELEASEspring-boot-starter-data-jpa 完美配合。

您的问题可能是@OneToOne(mappedBy = "obejctTwo"),因为此映射不存在。

对象

@Entity
public class Object {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long refnno;

    @OneToOne(mappedBy = "object",
            cascade = CascadeType.ALL,
            orphanRemoval = true)
    private ObjectDetail objectDetail;

    private String type;

    private String status;

    public setObjectDetail(ObjectDetail objectDetail) {
        this.objectDetail = objectDetail;
        objectDetail.setObject = this;
    }

    // Getters and remaining setters...
}

我为objectDetail 添加了一个稍微修改的设置器,这有助于保持双向OneToOne 映射同步。

顺便说一句:我将refnno 的数据类型更改为对象Long。类被认为更适合数据库实体,因为您可以正确地测试它们是否为空。此外,此 id 还可用于JpaRepository<Object, Long>

对象详细信息

@Entity
public class ObjectDetail {

    @Id
    private Long refnno;

    @OneToOne
    @JoinColumn(name = "refnno")
    @MapsId
    private Object object;

    private String policyNo;

    private String depNo;

    // Getters and setters...
}

存储库和执行

我创建了一个简单的存储库。

public interface ObjectRepository extends JpaRepository<Object, Long> {
}

然后我使用save(Object entity) 方法将新的Object 与新的ObjectDetail 保持一致。

Object object = new Object();
object.setType("new");
ObjectDetail objectDetail = new ObjectDetail();
objectDetail.setPolicyNo = "999";

object.setObjectDetail(objectDetail);

objectRepository.save(object);

【讨论】:

  • 似乎不起作用。由于 objectDetail 中的 refnno 是 PK 并且我们在保存到存储库时不知道 refnno。错误消息:对象引用了一个未保存的瞬态实例 - 在刷新之前保存瞬态实例
  • @JeffreyChu 我试过了,它奏效了。我在答案中添加了我的代码。您的问题可能是您的错误映射@OneToOne(mappedBy = "obejctTwo")
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-11-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-11-29
  • 2017-08-28
相关资源
最近更新 更多