Я пытался реализовать двунаправленные отношения между моими сущностями.
Студент
@Table(name = "students")
@Entity
public class Student {
@Id
// @GeneratedValue(strategy = GenerationType.AUTO)
private long album;
@NotNull
private String name;
@NotNull
private String surname;
@OneToMany(mappedBy = "student", cascade = {CascadeType.PERSIST, CascadeType.MERGE, CascadeType.DETACH, CascadeType.REFRESH})
private List<StudentSection> studentSections;
@Transactional(propagation=Propagation.REQUIRED, readOnly=true, noRollbackFor=Exception.class)
public void addSection(Section section){
if(this.studentSections == null){
this.studentSections = new ArrayList<>();
}
StudentSection studentSectionToAdd = new StudentSection();
studentSectionToAdd.setStudent(this);
studentSectionToAdd.setSection(section);
this.studentSections.add(studentSectionToAdd); //here
section.addStudentSection(studentSectionToAdd);
}
}
связующий объект в связи ManyToMany
@Table(name = "student_section")
@Entity
public class StudentSection {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
private Integer grade;
private Date date;
@NotNull
@ManyToOne(cascade = {CascadeType.PERSIST, CascadeType.MERGE, CascadeType.DETACH, CascadeType.REFRESH})
@JoinColumn(name = "student_id")
private Student student;
@NotNull
@ManyToOne(cascade = {CascadeType.PERSIST, CascadeType.MERGE, CascadeType.DETACH, CascadeType.REFRESH})
@JoinColumn(name = "section_id")
private Section section;
}
и Раздел
@Table(name = "sections")
@Entity
public class Section {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
@NotNull
private String name;
@NotNull
private Integer sizeOfSection;
@NotNull
private Boolean isActive;
@OneToMany(mappedBy = "section", cascade = {CascadeType.PERSIST, CascadeType.MERGE, CascadeType.DETACH, CascadeType.REFRESH})
private List<StudentSection> studentSections;
void addStudentSection(StudentSection studentSection){
if(this.studentSections == null){
this.studentSections = new ArrayList<>();
}
this.studentSections.add(studentSection);
}
}
Я столкнулся с проблемой с методом Student.addSection (). При попытке выполнить это я получил ошибку в строке this.studentSections.add(studentSectionToAdd);
, сказав
failed to lazily initialize a collection of role: Student.studentSections, could not initialize proxy - no Session
, что я прочитал об этом и обнаружил, что лучший способ исправить это - добавить аннотацию @Transactional к методу, однако это ничего не изменило и я не могу заставить его работать. Я также попытался переместить метод Student.addSection () в StudentServiceImpl
@Service
@Primary
public class StudentServiceImpl implements StudentService {
protected StudentRepository studentRepository;
@Autowired
public StudentServiceImpl(StudentRepository studentRepository) {
this.studentRepository = studentRepository;
}
@Override
@Transactional(propagation = Propagation.REQUIRED, readOnly = true, noRollbackFor = Exception.class)
public void addSection(Student student, Section section) {
if (student.getStudentSections() == null) {
student.setStudentSections(new ArrayList<>());
}
StudentSection studentSectionToAdd = new StudentSection();
studentSectionToAdd.setStudent(student);
studentSectionToAdd.setSection(section);
student.getStudentSections().add(studentSectionToAdd);
//section.addStudentSection(studentSectionToAdd);
}
}
, но все еще получил ошибку.
Я также использую CrudRepository для извлечения сущностей из базы данных.
@Repository
public interface StudentRepository extends CrudRepository<Student, Long> {
Student findByName(String name);
}
Здесь я вызываю метод
@Component
public class DatabaseLoader implements CommandLineRunner {
private final StudentRepository studentRepository;
private final SectionRepository sectionRepository;
private final StudentSectionRepository studentSectionRepository;
private final StudentService studentService;
@Autowired
public DatabaseLoader(StudentRepository studentRepository, SectionRepository sectionRepository, StudentSectionRepository studentSectionRepository,
StudentService studentService) {
this.studentRepository = studentRepository;
this.sectionRepository = sectionRepository;
this.studentSectionRepository = studentSectionRepository;
this.studentService = studentService;
}
@Override
public void run(String... strings) throws Exception {
//Testing entities
Student student = new Student();
student.setAlbum(1L);
student.setName("student");
student.setSurname("test");
this.studentRepository.save(student);
Section section = new Section();
section.setName("section");
section.setSizeOfSection(10);
section.setIsActive(true);
this.sectionRepository.save(section);
//end
//Adding Student to a Section test
Student student1 = studentRepository.findByName("student");
//student1.setStudentSections(this.studentSectionRepository.findAllByStudent(student1));
Section section1 = sectionRepository.findByName("section");
//section1.setStudentSections(this.studentSectionRepository.findAllByStudent(student1));
studentService.addSection(student1, section1);
this.studentRepository.save(student1);
//end test
}
}
Также, когда я извлекаю списки StudentSection из базы данных здесь и устанавливаю их в оба объекта перед добавлением нового отношения, все работает нормально, но это не совсем то решение, к которому я иду.