自动从字段中休眠Hibernate Map ID

自动从字段中休眠Hibernate Map ID

问题描述:

我有类似的东西:

@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中执行层叠"时,在调用save()之前必须手动分配此类的ID.

ClaimReturnInfo Id is not autogenerated because we want to propagate the Id from its parent (Claim). We are not able to do this automatically and we are getting this error: ids for this class must be manually assigned before calling save() when 'cascade' is executed in ClaimReturnInfo .

是否可以将Claim Id映射到ClaimReturnInfo Id还是我们应该手动进行?

Is it possible to map Claim Id into ClaimReturnInfo Id or should we do this manually?

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

Even if we set this ID manually on claimReturnInfo and we can perform updates, we still get this error when trying to create a new Claim:

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

服务实现中:

@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;
}

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

I have tried using the following mappings and from your comments it was apparent that Json object is populated correctly. I have noticed that the annotation @MapsId is the culprit.If you check the documentation of @MapsId annotation it says

Blockquote

Blockquote

组合键中的属性名称 *关系属性对应的*.如果不 *提供,该关系映射实体的主要对象 *键

The name of the attribute within the composite key * to which the relationship attribute corresponds. If not * supplied, the relationship maps the entity's primary * key

Blockquote

Blockquote

如果将@MapsId("Claim_idClaim")更改为@MapsId,它将开始保留您的实体.

If you change @MapsId("Claim_idClaim") to @MapsId it will start persisting your entities.

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;
    }
}