我知道这可能是一个普遍的问题,但到目前为止我找不到任何解决方案。
我有以下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;
}