我知道这可能是一个普遍的问题,但到目前为止我找不到任何解决方案。

我有以下2个实体:任务和代表。这两个实体分别具有主键:


MissionId [idImpXml,代码,类别]
RepresentationId [idImpXml,codeRepresentation]


制图表达与任务之间存在一对多的关系,这意味着每个任务都有一个制图表达,并且每个制图表达可用于不同的任务。

我使用JPA存储库将实体持久存储在数据库中:

public interface RepresentationDao extends JpaRepository <Representation, RepresentationId>

public interface MissionDao extends JpaRepository <Mission, MissionId>


我需要先保存一组表示形式,然后再保存一组任务。
制图表达正常工作,但是当我尝试保存任务时,制图表达的外键仍然为空。

这是我的代码:

// here representations are already persisted (in a separate transaction)..

RepresentationId representationId = new RepresentationId(idImpXml, codeRepresentation);
Representation representation = representationDao.findOne(representationId);

// representation is retrieved correctly

MissionId missionId = new MissionId(idImpXml, code, categorie);
Mission mission = new Mission(missionId, representation, label);

// I try to save the mission
missionDao.saveAndFlush(mission);

// THE FOREIGN KEY THAT SHOULD REFERENCE THE REPRESENTATION (CODE_REPRESENTATION) REMAINS NULL


任务

@Entity
@Table(name = "MISSION", schema = "dbo", catalog ="TEST")
public class Mission implements java.io.Serializable {

    private MissionId id;
    private Representation representation;
    private String label;

    public Mission() {
    }

    public Mission(MissionId id, Representation representation, String label) {
        this.id = id;
        this.representation = representation;
        this.label = label;
    }

    @EmbeddedId
    @AttributeOverrides({
            @AttributeOverride(name = "idImpXml", column = @Column(name = "ID_IMP_XML", nullable = false, precision = 38, scale = 0)),
            @AttributeOverride(name = "code", column = @Column(name = "CODE", nullable = false)),
            @AttributeOverride(name = "categorie", column = @Column(name = "CATEGORIE", nullable = false)) })
    public MissionId getId() {
        return this.id;
    }

    public void setId(MissionId id) {
        this.id = id;
    }


    @MapsId("ID_IMP_XML")
    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumns(
        value={ @JoinColumn(name = "ID_IMP_XML", referencedColumnName = "ID_IMP_XML", updatable=false),
                @JoinColumn(name = "CODE_REPRESENTATION", referencedColumnName = "CODE_REPRESENTATION", insertable=true, updatable=true)
            })
    public Representation getRepresentation() {
        return this.representation;
    }

    public void setRepresentation(Representation representation) {
        this.representation = representation;
    }

    @Column(name = "LABEL", nullable = false)
    public String getLabel() {
        return this.label;
    }

    public void setLabel(String label) {
        this.label = label;
    }


}


MissionId

@Embeddable
public class MissionId implements java.io.Serializable {

    private Long idImpXml;
    private String code;
    private int categorie;

    public MissionId() {
    }

    public MissionId(Long idImpXml, String code, int categorie) {
        this.idImpXml = idImpXml;
        this.code = code;
        this.categorie = categorie;
    }

    @Column(name = "ID_IMP_XML", nullable = false, precision = 38, scale = 0)
    public Long getIdImpXml() {
        return this.idImpXml;
    }

    public void setIdImpXml(Long idImpXml) {
        this.idImpXml = idImpXml;
    }

    @Column(name = "CODE", nullable = false)
    public String getCode() {
        return this.code;
    }

    public void setCode(String code) {
        this.code = code;
    }

    @Column(name = "CATEGORIE", nullable = false)
    public int getCategorie() {
        return this.categorie;
    }

    public void setCategorie(int categorie) {
        this.categorie = categorie;
    }

    public boolean equals(Object other) {
        if ((this == other))
            return true;
        if ((other == null))
            return false;
        if (!(other instanceof MissionId))
            return false;
        MissionId castOther = (MissionId) other;

        return ((this.getIdImpXml() == castOther.getIdImpXml()) || (this.getIdImpXml() != null
                && castOther.getIdImpXml() != null && this.getIdImpXml().equals(castOther.getIdImpXml())))
                && ((this.getCode() == castOther.getCode()) || (this.getCode() != null && castOther.getCode() != null
                        && this.getCode().equals(castOther.getCode())))
                && (this.getCategorie() == castOther.getCategorie());
    }

    public int hashCode() {
        int result = 17;

        result = 37 * result + (getIdImpXml() == null ? 0 : this.getIdImpXml().hashCode());
        result = 37 * result + (getCode() == null ? 0 : this.getCode().hashCode());
        result = 37 * result + this.getCategorie();
        return result;
    }

}


表示

@Entity
@Table(name = "REPRESENTATION", schema = "dbo", catalog ="TEST")
public class Representation implements Serializable {

    private RepresentationId id;
    private Long colorPattern;
    private String typePattern;
    private Integer thickness;

    public Representation() {
    }

    public Representation(RepresentationId id) {
        this.id = id;
    }

    public Representation(RepresentationId id, Long colorPattern, String typePattern,
            Integer thickness, Long codeCouleurPattern2, String typePattern2, Integer epaisseurPattern2) {
        this.id = id;
        this.colorPattern = colorPattern;
        this.typePattern = typePattern;
        this.thickness = thickness;
    }

    @EmbeddedId

    @AttributeOverrides({
            @AttributeOverride(name = "idImpXml", column = @Column(name = "ID_IMP_XML", nullable = false, precision = 38, scale = 0)),
            @AttributeOverride(name = "codeRepresentation", column = @Column(name = "CODE_REPRESENTATION", nullable = false)) })
    public RepresentationId getId() {
        return this.id;
    }

    public void setId(RepresentationId id) {
        this.id = id;
    }

    @Column(name = "COLOR_PATTERN")
    public Long getColorPattern() {
        return this.colorPattern;
    }

    public void setColorPattern(Long colorPattern) {
        this.colorPattern = colorPattern;
    }

    @Column(name = "TYPE_PATTERN")
    public String getTypePattern() {
        return this.typePattern;
    }

    public void setTypePattern(String typePattern) {
        this.typePattern = typePattern;
    }

    @Column(name = "THICKNESS")
    public Integer getThickness() {
        return this.thickness;
    }

    public void setThickness(Integer thickness) {
        this.thickness = thickness;
    }

}


RepresentationId

@Embeddable
public class RepresentationId implements java.io.Serializable {

    private Long idImpXml;
    private int codeRepresentation;

    public RepresentationId() {
    }

    public RepresentationId(Long idImpXml, int codeRepresentation) {
        this.idImpXml = idImpXml;
        this.codeRepresentation = codeRepresentation;
    }

    @Column(name = "ID_IMP_XML", nullable = false, precision = 38, scale = 0)
    public Long getIdImpXml() {
        return this.idImpXml;
    }

    public void setIdImpXml(Long idImpXml) {
        this.idImpXml = idImpXml;
    }

    @Column(name = "CODE_REPRESENTATION", nullable = false)
    public int getCodeRepresentation() {
        return this.codeRepresentation;
    }

    public void setCodeRepresentation(int codeRepresentation) {
        this.codeRepresentation = codeRepresentation;
    }

    public boolean equals(Object other) {
        if ((this == other))
            return true;
        if ((other == null))
            return false;
        if (!(other instanceof RepresentationId))
            return false;
        RepresentationId castOther = (RepresentationId) other;

        return ((this.getIdImpXml() == castOther.getIdImpXml()) || (this.getIdImpXml() != null
                && castOther.getIdImpXml() != null && this.getIdImpXml().equals(castOther.getIdImpXml())))
                && (this.getCodeRepresentation() == castOther.getCodeRepresentation());
    }

    public int hashCode() {
        int result = 17;

        result = 37 * result + (getIdImpXml() == null ? 0 : this.getIdImpXml().hashCode());
        result = 37 * result + this.getCodeRepresentation();
        return result;
    }

}

最佳答案

尝试通过在对象中添加另一个字段来覆盖列定义,并在@JoinColum中将可插入和可更新属性设置为false,如下所示:

@MapsId("ID_IMP_XML")
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumns(
    value={ @JoinColumn(name = "ID_IMP_XML", referencedColumnName = "ID_IMP_XML", insertable=false, updatable=false),
            @JoinColumn(name = "CODE_REPRESENTATION", referencedColumnName = "CODE_REPRESENTATION", insertable=false, updatable=false)
        })
public Representation getRepresentation() {
    return this.representation;
}

private Integer representationCode;
@Column(name = "CODE_REPRESENTATION")
public Integer getRepresentationCode() {
    return this.representationCode;
}

08-16 04:24