【问题标题】:Hibernate Map ID automatically from field从字段中自动休眠地图 ID
【发布时间】:2020-04-04 12:35:35
【问题描述】:

我有类似的东西:

@Entity
@Table(name = "claim", schema = "test")
public class Claim implements Serializable {

   @Id
   @GeneratedValue(strategy = GenerationType.AUTO)
   @Column(name = "idClaim", unique = true, nullable = false)
   private Integer idClaim;

   @OneToOne(mappedBy = "claim", cascade = CascadeType.ALL, fetch = FetchType.LAZY)
   @JsonManagedReference
   private ClaimReturnInfo claimReturnInfo;

   @Column(name = "notes")
   private String notes;

   // Getters and setters
}


@Entity
@Table(name = "claim_returninfo", schema = "test")
public class ClaimReturnInfo implements Serializable {

   @Id
   @Column(name = "Claim_idClaim")
   private Integer id;

   @MapsId("Claim_idClaim")
   @OneToOne(fetch = FetchType.LAZY)
   @JoinColumn(name = "Claim_idClaim")
   @JsonBackReference
   private Claim claim;

   @Column(name = "description")
   private String description;

   // Getters and setters
}

ClaimReturnInfo Id 不是自动生成的,因为我们想从其父级 (Claim) 传播 Id。我们无法自动执行此操作,并且出现此错误:当在 ClaimReturnInfo 中执行 'cascade' 时,必须在调用 save() 之前手动分配此类的 id。

是否可以将 Claim Id 映射到 ClaimReturnInfo Id 或者我们应该手动执行此操作?

即使我们在 claimReturnInfo 上手动设置此 ID 并且我们可以执行更新,但在尝试创建新的 Claim 时仍然会出现此错误:

// POST -> claimRepository.save() -> Error
{
    "notes": "Some test notes on a new claim",
    "claimReturnInfo": {
        "description": "Test description for a new claimReturnInfo"
    }
}

ServiceImplementation中:

@Override
@Transactional
public Claim save(Claim claim) throws Exception {
    if(null != claim.getClaimReturnInfo()) {
        claim.getClaimReturnInfo().setId(claim.getIdClaim());
    }

    Claim claimSaved = claimRepository.save(claim);
    return claimSaved;
}

【问题讨论】:

  • 是的,你需要先保存claim
  • 当然,如果我先保存 claim 并手动将此 ID 设置为其子项,则它可以工作。我要求一种自动行为。
  • 你在使用Spring Rest Repositories吗?请在失败的地方添加代码。 \
  • 你的意思是Spring data repository?是的,我正在使用JpaRepository。正如我在问题中所说,失败的代码只是.save
  • 我认为这篇文章应该对stackoverflow.com/questions/57116212/…有所帮助。您需要在父实体中添加setter方法,以便它可以为您绑定子实体。

标签: java hibernate spring-boot jpa spring-data-jpa


【解决方案1】:

我已尝试使用以下映射,并且从您的 cmets 可以看出 Json 对象已正确填充。 我注意到注释@MapsId 是罪魁祸首。如果您查看@MapsId 注释的文档,它会说

块引用

复合键中的属性名称 * 关系属性所对应的。如果不 * 提供,关系映射实体的主要 * 键

块引用

如果您将@MapsId("Claim_idClaim") 更改为@MapsId,它将开始持久化您的实体。

import javax.persistence.*;

@Entity
@Table(name = "CLAIM")
public class Claim {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Column(name = "idClaim", unique = true, nullable = false)
    private Long idClaim;
    @Column(name = "notes")
    private String notes;

    @OneToOne(mappedBy = "claim", cascade = CascadeType.ALL, optional = false)
    private ClaimReturnInfo claimReturnInfo;

    public Long getIdClaim() {
        return idClaim;
    }

    public String getNotes() {
        return notes;
    }

    public void setNotes(String notes) {
        this.notes = notes;
    }


    public ClaimReturnInfo getClaimReturnInfo() {
        return claimReturnInfo;
    }

    public void setClaimReturnInfo(ClaimReturnInfo claimReturnInfo) {
        if (claimReturnInfo == null) {
            if (this.claimReturnInfo != null) {
                this.claimReturnInfo.setClaim(null);
            }
        } else {
            claimReturnInfo.setClaim(this);
        }
        this.claimReturnInfo = claimReturnInfo;
    }

}


package com.hiber.hiberelations;

import javax.persistence.*;

@Entity
@Table(name = "CLAIM_RETURN_INFO")
public class ClaimReturnInfo {

    @Id
    @Column(name = "Claim_idClaim")
    private Long childId;


    @Column(name = "DESCRIPTION")
    private String description;

    @MapsId
    @OneToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "Claim_idClaim")
    private Claim claim;

    public Long getChildId() {
        return childId;
    }

    public String getDescription() {
        return description;
    }

    public void setDescription(String description) {
        this.description = description;
    }

    public Claim getClaim() {
        return this.claim;
    }

    public void setClaim(Claim claim) {
        this.claim = claim;
    }
}

【讨论】:

    猜你喜欢
    • 2011-01-01
    • 1970-01-01
    • 2018-07-31
    • 2010-10-22
    • 1970-01-01
    • 2015-04-21
    • 1970-01-01
    • 2014-02-15
    相关资源
    最近更新 更多