0

У меня есть следующие объекты: MissionInfo:поле не инициализируется, когда сохраняются объекта с помощью 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 = 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 

Дерево объектов сохранено правильно, createdMissionInfo имеет список с одной миссией. НО после сохранения одного объекта миссии (createdMissionInfo.getMissions(). Get (0)) имеют NULL в MissionInfoId и missionInfo.

Можно настроить элементы 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(); 

Спасибо!

UPDATE:

правлю объектов в соответствии с 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 

ответ

1

Вы предположение не совсем правильно.

  • Не MissionInfo является стороной владеющим, но Mission. Собственная сторона - это та, которая хранит информацию о взаимоотношениях. В отношениях «все-к-одному» много сторона является областью, так как она должна хранить одну FK до одной стороны.

  • Ваш класс MissionInfo не участвует в той же работе, что и у Mission. Для того, чтобы сделать это, удалите joinColumn аннотацию и добавить атрибут mappedBy для missions поля:

    @OneToMany(cascade=CascadeType.ALL, mappedBy="missionInfo") 
    private List<Mission> missions; 
    
  • Вы можете удалить missionInfoId поле из Mission. Столбец Thsi уже присутствует из-за аннотации joinColumn в поле missionInfo.

  • Если вы сделаете joinColumn не вставленным и не обновляемым, вы не сможете добавлять данные отношений.Удалить эти атрибуты:

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

сохраняющийся код должен работать.

EDIT: Я думал, что каскад на MissionInfo позаботится об экономии. Я не знаю, почему это не срабатывает. Что вы можете сделать, чтобы обойти это, - установить данные отношений на стороне владельца, то есть Mission. Тогда вам не нужно полагаться на каскад:

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

Спасибо за ответ, но у меня снова возникла проблема. Пожалуйста, просмотрите мое сообщение. Благодаря! –

+0

Добро пожаловать :) По моему опыту, каскад должен был быть запущен. Добавили обходной путь к вопросу. Посмотрите, поможет ли это. – kostja

+0

, когда я пытаюсь сохранить миссию с заданием миссии, у меня есть исключение: org.hibernate.TransientPropertyValueException: объект ссылается на несохраненный экземпляр переходного процесса - сохранить временный экземпляр перед сбросом: package.domain.Mission.missionInfo -> package.domain.MissionInfo –