How to stop hibernate to do select before insert in child table in @ManyToOne mapping?

Deadly 提交于 2019-12-13 07:58:55

问题


How to stop hibernate to do select before insert in child table in many to one mapping?

I have a student table :

    @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;
        }
    }

I have a Class table:

@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;
    }
}

Whenever i do studentRepo.save(studentEntity) it always do select from parent class i.e. Class table then if the data exists in the parent table then it do insert in child table i.e. student. Cannot it happen in a single network call rather then hitting two calls first select from parent then insert.


回答1:


If I understand you correctly, you want to save or use existing class (if exists) within the same call. The performance-best way to do this is to insert and handle exception in case of failure. However, the best practice is to make separate requests to the database: first, to check if the class exists; second, to insert it (if needed), and then insert a student. My advice to you would be to create a separate @Transactional service method, that would execute that operation for you. Just like this:

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);
}

Just make sure you add the package name to your class class, otherwise, compiler will think of java.lang.Class.



来源:https://stackoverflow.com/questions/56756965/how-to-stop-hibernate-to-do-select-before-insert-in-child-table-in-manytoone-ma

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!