使用 JPARepository 持久化对象时未初始化字段,@OneToMany <=> @ManyToOne



我有以下实体:任务信息:

@Entity
@Table(name = "mission_info")
public class MissionInfo implements Serializable {
@Id
@Column(name = "id")
@GeneratedValue
private Long id;
@OneToMany(cascade={CascadeType.ALL})
@JoinColumn(name="mission_info_id")
private List<Mission> missions;
public MissionInfo() {
}
// getters and setters
}

使命:

@Entity
@Table(name = "mission")
public class Mission implements Serializable {
@Id
@Column(name = "id")
@GeneratedValue
private Long id;
@Column(name = "mission_info_id")
private Long missionInfoId;
@ManyToOne
@JoinColumn(name="mission_info_id", insertable=false, updatable=false)
private MissionInfo missionInfo;
public Mission() {
}
// getters and setters
}

正如我在这个方案所有者方面所理解的那样-MissionInfo

我使用以下代码进行保存:MissionInfo info=新的MissionInfo();

Mission o = new Mission();
List<Mission> list = new ArrayList<Mission>();
list.add(o);
info.setMissions(list);
MissionInfo createdMissionInfo = missionInfoRepository.save(info);
MissionInfo mi = createdMissionInfo.getMissions().get(0).getMissionInfo(); <-- NULL
Long mId = createdMissionInfo.getMissions().get(0).getMissionInfoId(); <-- NULL

对象树保存正确,createdMissionInfo有一个包含一个任务的列表。但是保存单个任务对象后(createdMissionInfo.getMissions().get(0))在missionInfoId和missionInfo中具有NULL。

是否可以调整保存后将具有实际值的jpa/hibernate实体?像这样:

// should be a pointer to saved mission info
createdMissionInfo.getMissions().get(0).getMissionInfo(); 
// should be a id of saved mission info
createdMissionInfo.getMissions().get(0).getMissionInfoId();

谢谢!

更新:

我根据kostja评论更正实体:

@Entity
@Table(name = "mission_info")
public class MissionInfo implements Serializable {
@Id
@Column(name = "id")
@GeneratedValue
private Long id;
@OneToMany(mappedBy = "missionInfo", cascade=CascadeType.ALL)
private List<Mission> missions;
}

@Entity
@Table(name = "mission")
public class Mission implements Serializable {
@Id
@Column(name = "id")
@GeneratedValue
private Long id;
@ManyToOne
@JoinColumn(name="mission_info_id")
private MissionInfo missionInfo;
}

但是当我保存使用这个代码:

MissionInfo info = new MissionInfo();
Mission o = new Mission();
List<Mission> list = new ArrayList<Mission>();
list.add(o);
info.setMissions(list);
MissionInfo createdMissionInfo = missionInfoRepository.save(info);

sql外键"mission_info_id"为NULL。我的主要问题还没有解决:

MissionInfo mi = createdMissionInfo.getMissions().get(0).getMissionInfo(); <-- NULL

您的假设并不完全正确。

  • 不是MissionInfo是拥有方,而是Mission。拥有方是存储关系信息的一方。在多对一关系中,侧是自己的一个,因为它必须将单个FK存储到一侧。

  • 您的MissionInfo类与Mission不属于同一关系。为此,请删除joinColumn注释并为missions字段添加mappedBy属性:

    @OneToMany(cascade=CascadeType.ALL, mappedBy="missionInfo")
    private List<Mission> missions;
    
  • 您可以从Mission中删除missionInfoId字段。由于missionInfo字段上存在joinColumn注释,因此该列已存在。

  • 如果将joinColumn设置为不可插入和不可更新,则将无法添加任何关系数据。删除这些属性:

    @ManyToOne
    @JoinColumn(name="mission_info_id")
    private MissionInfo missionInfo; 
    

持久化代码现在应该可以工作了。

编辑:我以为MissionInfo上的级联可以节省开支。我不知道为什么它没有被触发。要解决这个问题,您可以在拥有方设置关系数据,即Mission。那么你就不必依赖级联:

Mission o = new Mission();
o.setMissionInfo(info);
// persist Mission

相关内容

最新更新