使用 Hibernate 插入嵌套实体
Inserting nested entities using Hibernate
我想弄清楚如何正确地将多个实体插入到数据库中,这些实体具有另一个实体作为字段,并且在休眠中这似乎是一项非常重要的任务。当我把所有东西都整理得井井有条时,它工作正常,但是一旦它们交叉链接,它就无法按预期工作。我假设我缺少一些使其工作所需的注释,但经过几个小时的谷歌搜索后,我找不到任何 suitable 来及时解决它。
我目前的实体是这样设置的 我有一个学生和
@Entity
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Student {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;
private String name;
}
我有一个教室,里面有一个学生实体,通过它的 id
@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,当我尝试将它存储到数据库中时,它工作得很好:
{
"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 (?, ?)
它中断:
错误:在 table "class_room" 上插入或更新违反了外键约束 "fk_student"
详细信息:密钥 (student_id)=(3) 不存在于 table "student".
中
这可能是我正在实现的逻辑,我正在尝试以这种方式存储它们:
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);
但是我不知道如何先单独存储学生,然后再存储classRooms。
感谢任何帮助。希望随着时间的推移解决它,如果是这样,我会 post 自己回答。
您的 id 方法是 @GeneratedValue(strategy = GenerationType.IDENTITY)
,而您的学生和班级列表都预先填充了 id。如果你想让那些 id 进入 json,删除 @GeneratedValue(strategy = GenerationType.IDENTITY)
注释。
我想弄清楚如何正确地将多个实体插入到数据库中,这些实体具有另一个实体作为字段,并且在休眠中这似乎是一项非常重要的任务。当我把所有东西都整理得井井有条时,它工作正常,但是一旦它们交叉链接,它就无法按预期工作。我假设我缺少一些使其工作所需的注释,但经过几个小时的谷歌搜索后,我找不到任何 suitable 来及时解决它。
我目前的实体是这样设置的 我有一个学生和
@Entity
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Student {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;
private String name;
}
我有一个教室,里面有一个学生实体,通过它的 id
@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,当我尝试将它存储到数据库中时,它工作得很好:
{
"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 (?, ?)
它中断:
错误:在 table "class_room" 上插入或更新违反了外键约束 "fk_student" 详细信息:密钥 (student_id)=(3) 不存在于 table "student".
中这可能是我正在实现的逻辑,我正在尝试以这种方式存储它们:
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);
但是我不知道如何先单独存储学生,然后再存储classRooms。 感谢任何帮助。希望随着时间的推移解决它,如果是这样,我会 post 自己回答。
您的 id 方法是 @GeneratedValue(strategy = GenerationType.IDENTITY)
,而您的学生和班级列表都预先填充了 id。如果你想让那些 id 进入 json,删除 @GeneratedValue(strategy = GenerationType.IDENTITY)
注释。