I have following entities: MissionInfo:
@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
}
Mission:
@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
}
As I understood in this scheme owner side - MissionInfo
I use following code for saving: 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);
MissionInfo mi = createdMissionInfo.getMissions().get(0).getMissionInfo(); <-- NULL
Long mId = createdMissionInfo.getMissions().get(0).getMissionInfoId(); <-- NULL
Object tree saved correctly, createdMissionInfo have list with one Mission. BUT after saving single mission object (createdMissionInfo.getMissions().get(0)) have NULLs in missionInfoId and missionInfo.
It is possible to tune jpa/hibernate entities that AFTER SAVING will have actual values? Like this:
// 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();
Thanks!
UPDATE:
I correct entities according to kostja comment:
@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;
}
But when I save using this code:
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 foreign key 'mission_info_id' is NULL. And my main question in not resolved:
MissionInfo mi = createdMissionInfo.getMissions().get(0).getMissionInfo(); <-- NULL
You assumptions are not entirely correct.
Not the
MissionInfois the owning side, butMission. The owning side is the one storing the relationship information. In many-to-one relationships, the many side is the ownining one, since it has to store a single FK to the one side.Your
MissionInfoclass does not participate in the same relationship as theMission. In order to do so, remove thejoinColumnannotation and add amappedByattribute for themissionsfield:You can remove the
missionInfoIdfield fromMission. Thsi column is already present due to the joinColumn annotation on themissionInfofield.If you make the joinColumn non-insertable and non-updateable, you will not be able able to add any relationship data. Remove those attributes:
The persisting code should work now.
EDIT: I thought that the cascade on the
MissionInfowould take care of the saving. I dont know why it is not being triggered. What you can do to work around that, is to set the relationship data on the owning side, i.e.Mission. Then you don't have to rely on the cascade: