Reputation: 606
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
Upvotes: 0
Views: 2582
Reputation: 61558
You assumptions are not entirely correct.
Not the MissionInfo
is the owning side, but Mission
. 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 MissionInfo
class does not participate in the same relationship as the Mission
. In order to do so, remove the joinColumn
annotation and add a mappedBy
attribute for the missions
field:
@OneToMany(cascade=CascadeType.ALL, mappedBy="missionInfo")
private List<Mission> missions;
You can remove the missionInfoId
field from Mission
. Thsi column is already present due to the joinColumn annotation on the missionInfo
field.
If you make the joinColumn non-insertable and non-updateable, you will not be able able to add any relationship data. Remove those attributes:
@ManyToOne
@JoinColumn(name="mission_info_id")
private MissionInfo missionInfo;
The persisting code should work now.
EDIT: I thought that the cascade on the MissionInfo
would 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:
Mission o = new Mission();
o.setMissionInfo(info);
// persist Mission
Upvotes: 2