Вставка вложенных объектов с помощью Hibernate - PullRequest
0 голосов
/ 01 мая 2020

Я пытаюсь выяснить, как правильно вставить в базу данных несколько объектов, у которых есть другие объекты в качестве полей, и кажется, что в спящем режиме это немного нетривиальная задача. Это работает нормально, когда у меня все упорядочено и аккуратно, но как только они сшиты, это работает не так, как хотелось бы. Я предполагаю, что я пропускаю некоторые необходимые аннотации, чтобы заставить это работать, но после нескольких часов поиска в Google, я не могу найти ничего подходящего, чтобы решить это быстро.

Мои текущие сущности настроены таким образом, у меня есть ученик и

@Entity
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Student {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private int id;
    private String name;
}

И у меня есть классная комната, в которой сущность Студента связана с ее идентификатором

@Entity
@Data
@NoArgsConstructor
@AllArgsConstructor
public class ClassRoom {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "student_id", foreignKey = @ForeignKey(name = "fk_student"))
    private Student student;

    private String dateCreated;
}

И у меня есть json, который прекрасно работает, когда я пытаюсь сохранить его в db:

{
   "dateCreated":"17",
   "body":[
      {
         "id":1,
         "student":{
            "id":1,
            "name":"petya",
            "hibernateLazyInitializer":{

            }
         },
         "dateCreated":"17"
      },
      {
         "id":2,
         "student":{
            "id":2,
            "name":"petrya",
            "hibernateLazyInitializer":{

            }
         },
         "dateCreated":"17"
      },
      {
         "id":3,
         "student":{
            "id":3,
            "name":"slon",
            "hibernateLazyInitializer":{

            }
         },
         "dateCreated":"17"
      }
   ]
}

Hibernate: select student0_.id as id1_1_0_, student0_.name as name2_1_0_ from json_schema.student student0_ where student0_.id=?
Hibernate: select student0_.id as id1_1_0_, student0_.name as name2_1_0_ from json_schema.student student0_ where student0_.id=?
Hibernate: select student0_.id as id1_1_0_, student0_.name as name2_1_0_ from json_schema.student student0_ where student0_.id=?
Hibernate: select classroom0_.id as id1_0_0_, classroom0_.date_created as date_cre2_0_0_, classroom0_.student_id as student_3_0_0_ from json_schema.class_room classroom0_ where classroom0_.id=?
Hibernate: select classroom0_.id as id1_0_0_, classroom0_.date_created as date_cre2_0_0_, classroom0_.student_id as student_3_0_0_ from json_schema.class_room classroom0_ where classroom0_.id=?
Hibernate: select classroom0_.id as id1_0_0_, classroom0_.date_created as date_cre2_0_0_, classroom0_.student_id as student_3_0_0_ from json_schema.class_room classroom0_ where classroom0_.id=?
Hibernate: update json_schema.class_room set date_created=?, student_id=? where id=?
Hibernate: update json_schema.class_room set date_created=?, student_id=? where id=?
Hibernate: update json_schema.class_room set date_created=?, student_id=? where id=?

Но как только я пытаюсь сохранить запись второго класса, которая ссылается на третьего ученика, например, как этот:

{
   "dateCreated":"10",
   "body":[
      {
         "id":1,
         "student":{
            "id":1,
            "name":"petya",
            "hibernateLazyInitializer":{

            }
         },
         "dateCreated":"10"
      },
      {
         "id":2,
         "student":{
            "id":3,
            "name":"slon",
            "hibernateLazyInitializer":{

            }
         },
         "dateCreated":"10"
      },
      {
         "id":3,
         "student":{
            "id":2,
            "name":"petrya",
            "hibernateLazyInitializer":{

            }
         },
         "dateCreated":"10"
      }
   ]
}

Hibernate: select student0_.id as id1_1_0_, student0_.name as name2_1_0_ from json_schema.student student0_ where student0_.id=?
Hibernate: insert into json_schema.student (name) values (?)
Hibernate: select student0_.id as id1_1_0_, student0_.name as name2_1_0_ from json_schema.student student0_ where student0_.id=?
Hibernate: insert into json_schema.student (name) values (?)
Hibernate: update json_schema.student set name=? where id=?
Hibernate: select classroom0_.id as id1_0_0_, classroom0_.date_created as date_cre2_0_0_, classroom0_.student_id as student_3_0_0_ from json_schema.class_room classroom0_ where classroom0_.id=?
Hibernate: insert into json_schema.class_room (date_created, student_id) values (?, ?)
Hibernate: select classroom0_.id as id1_0_0_, classroom0_.date_created as date_cre2_0_0_, classroom0_.student_id as student_3_0_0_ from json_schema.class_room classroom0_ where classroom0_.id=?
Hibernate: insert into json_schema.class_room (date_created, student_id) values (?, ?)

Разрывается с:

ОШИБКА: вставка или обновление таблицы "class_room" нарушает ограничение внешнего ключа "fk_student" Detail: Key (student_id) = (3) отсутствует в таблице " студент ".

Это может быть логика c Я реализую, я пытаюсь сохранить их таким образом:

final ClassRoom[] classRooms = objectMapper.readValue(parser, ClassRoom[].class);
        final List<ClassRoom> classRoomList = Arrays.asList(classRooms);
        final List<Student> studentsList = new ArrayList<>();
        for (final ClassRoom classRoom : classRoomList) {
            studentsList.add(classRoom.getStudent());

        }
        studentRepo.saveAll(studentsList);
        classRoomRepo.saveAll(classRoomList);

Но я не знаю, как отдельно Храните студентов сначала, и только после магазина. Ценю любую помощь. Надеюсь со временем все решу, если да, выложу ответ сам.

1 Ответ

1 голос
/ 02 мая 2020

ваш подход к идентификатору @GeneratedValue(strategy = GenerationType.IDENTITY), в то время как ваш список учеников и классная комната заполнены заранее. Если вы хотите, чтобы эти идентификаторы появлялись в json, удалите аннотацию @GeneratedValue(strategy = GenerationType.IDENTITY).

...