在多对一映射中插入子表之前如何停止休眠选择?
我有一个学生桌:
@Entity
@Table
@NoArgsConstructor
@AllArgsConstructor
@Builder
@Data
@IdClass(StudentId.class)
public class Student implements Persistable<StudentId> {
@Id
private String studentUuid;
@Id
private String studentName;
@Column
private String sex;
public Student(String studentUuid,String studentName){
this.studentUuid = studentUuid;
this.studentName = studentName;
}
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumns({
@JoinColumn(
name = "classUuid",referencedColumnName = "classUuid"),
@JoinColumn(
name = "className",referencedColumnName = "className")
})
private Class className;
@Override
public StudentId getId() {
return new StudentId().builder().studentName(studentName).studentUuid(studentUuid).build();
}
@Override
public boolean isNew() {
return true;
}
}
我有一个班级表:
@Entity
@Table
@Builder
@NoArgsConstructor
@AllArgsConstructor
@Data
@IdClass(ClassId.class)
public class Class implements Persistable<ClassId> {
@Id
private String classUuid;
@Id
private String className;
@Column
private String classRoomNo;
@Column
private String classSize;
@OneToMany(mappedBy = "className",cascade = CascadeType.ALL,fetch = FetchType.LAZY)
private List<Student> studentList;
@Override
public ClassId getId() {
return new ClassId().builder().className(className).classUuid(classUuid).build();
}
@Override
public boolean isNew() {
return true;
}
}
每当我执行studentRepo.save(studentEntity)时,它总是从父类中进行选择,即类表,然后如果该数据存在于父表中,那么它将插入子表即学生。 不能在单个网络通话中发生,而是先打两个通话,然后先从父级选择,然后插入。
答案 0 :(得分:0)
如果我对您的理解正确,那么您想在同一调用中保存或使用现有的类(如果存在)。执行此操作的最佳性能方法是在发生故障的情况下插入并处理异常。但是,最佳实践是对数据库进行单独的请求:首先,检查该类是否存在;第二,插入它(如果需要),然后插入一个学生。我对您的建议是创建一个单独的@Transactional
服务方法,该方法将为您执行该操作。就是这样:
private final ClassRepository classRepository;
@Transactional
public Student createStudent(Object studentDto) {
Class cls = classRepository.findByClassUuid(studentDto.getStudentClass().getClassUuid())
// in case it returns optional
.orElse(classRepository.save(Class.builder()
.className("..")
.classSize("..")
//...
.build()));
Student studentEntity = new Student();
// setters skipped
return studentRepo.save(studentEntity);
}
只需确保将包名称添加到class
类中,否则,编译器会想到java.lang.Class。