@Saintka

Почему при сохранении объекта через связь OneToMany — ManyToOne получаю ошибку?

Есть несколько Entity:

BaseModel Entity:

@Entity
    @Inheritance(strategy = InheritanceType.JOINED)
    public abstract class BaseModel {
    
        @Id
        @Column(name = "id")
        @Getter
        @GeneratedValue(strategy = GenerationType.AUTO)
        private long id;
    
        protected BaseModel() {
        }
    }

ClassRoom Entity:

@Entity
    @Table(name = "class_room")
    public final class ClassRoom extends BaseModel {
    
        @OneToMany(fetch = FetchType.LAZY, mappedBy = "classRoom" )
        @Getter
        @Setter
        private List<Teacher> teacher = new ArrayList<>();
    
        @OneToMany(fetch = FetchType.LAZY, mappedBy = "classRoom")
        @Getter
        @Setter
        private List<Pupil> pupil = new ArrayList<>();
    
        @Column(nullable = false)
        @Getter
        @Setter
        private String name;
    
        public ClassRoom() {
        }
    }


Pupil Entity:

@Entity
    @Table(name = "pupil")
    public final class Pupil extends BaseModel {
    
        @ManyToOne
        @JoinColumn(name = "pupil_id")
        @Setter
        private ClassRoom classRoom;
    
        @Column(nullable = false)
        @Getter
        @Setter
        private String name;
    
        @Getter
        @Setter
        @Column(nullable = false)
        private String surname;
        
        public Pupil() {
    
        }
    }


Teacher Entity:

@Entity
    @Table(name = "teacher")
    public final class Teacher extends BaseModel {
    
        @ManyToOne
        @JoinColumn(name = "teacher_id")
        @Setter
        private ClassRoom classRoom;
    
        @Column(nullable = false)
        @Getter
        @Setter
        private String name;
    
        @Column(nullable = false)
        @Getter
        @Setter
        private String surname;
    
        @Column(nullable = false)
        @Getter
        @Setter
        private String discipline;
    
        public Teacher() {
    
        }
    }

В консоль падает ошибка:

org.springframework.dao.DataIntegrityViolationException: not-null property references a null or transient value : com.SchoolJournal.SpringHibernate.model.Pupil.name; nested exception is org.hibernate.PropertyValueException: not-null property references a null or transient value : com.SchoolJournal.SpringHibernate.model.Pupil.name


Тест который написан для тестирования созданных объектов:

@SpringBootTest
    @TestInstance(TestInstance.Lifecycle.PER_CLASS)
    class SpringHibernateApplicationTests {

	@Autowired
	private PupilRepository pupilRepository;

	@Autowired
	private ClassRoomRepository classRoomRepository;

	@Autowired
	private TeacherRepository teacherRepository;

    @BeforeAll
    @Rollback(value = false)
    public void contextLoads() {
    	Pupil pupil = new Pupil();
    	pupil.setName("Anton");
    	pupil.setSurname("Savridov");
    
    	Pupil pupil1 = new Pupil();
    	pupil.setName("Elena");
    	pupil.setSurname("Antonova");
    
    	Teacher teacher = new Teacher();
    	teacher.setName("Alla");
    	teacher.setSurname("Aronova");
    	teacher.setDiscipline("Mathematics");
    
    	ClassRoom classRoom = new ClassRoom();
    	classRoom.setName("1A");
    	pupil.setClassRoom(classRoom);
    	pupil1.setClassRoom(classRoom);
    	teacher.setClassRoom(classRoom);
    
    	classRoomRepository.save(classRoom);
    	teacherRepository.save(teacher);
    	pupilRepository.save(pupil);
    	pupilRepository.save(pupil1);
    }
    
    @Test
    public void createEntity() {
    	Iterable<Pupil> allPupil = pupilRepository.findAll();
    	for (Pupil pupil1 : allPupil) {
    		System.out.println("Ученики");
    		System.out.println("----------------------------");
    		System.out.println(pupil1.getId() + " " +
    				pupil1.getName() + " " +
    				pupil1.getSurname());
    		System.out.println("----------------------------");
    	}
    
    	Iterable<Teacher> allTeacher = teacherRepository.findAll();
    	for (Teacher teacher1 : allTeacher) {
    		System.out.println("Учителя");
    		System.out.println("----------------------------");
    		System.out.println(teacher1.getId() + " " +
    				teacher1.getName() + " " +
    				teacher1.getSurname() + " " +
    				teacher1.getDiscipline());
    		System.out.println("----------------------------");
    	}
    	Iterable<ClassRoom> allClassRoom = classRoomRepository.findAll();
    	for (ClassRoom classRoom1 : allClassRoom) {
    		System.out.println("Класс");
    		System.out.println("----------------------------");
    		System.out.println(classRoom1.getId() + " "
    				+ classRoom1.getName());
    		System.out.println(classRoom1.getPupil().getId() + " " +
    				classRoom1.getPupil().getName() + " " +
    				classRoom1.getPupil().getSurname());
    		System.out.println(classRoom1.getTeacher().getId() + " " +
    				classRoom1.getTeacher().getName() + " " +
    				classRoom1.getTeacher().getSurname() + " " +
    				classRoom1.getTeacher().getDiscipline());
    		System.out.println("----------------------------");
    	}
    }


Если я использую связь OneToOne - ManyToOne, то все отрабатывает хорошо, но я не могу добавить нового Pupil например.
  • Вопрос задан
  • 91 просмотр
Пригласить эксперта
Ответы на вопрос 1
azerphoenix
@azerphoenix Куратор тега Java
Java Software Engineer
Добрый день!
Предположу, что у вас возникла проблема с тем, что в SQL есть зарезервированные слова и при создании таблиц и колонок у вас эти столбцы не создаются.

not-null property references a null or transient value : com.SchoolJournal.SpringHibernate.model.Pupil.name

В данном случае это название переменной Pupil.name
(433 строка) - Список зарезервированных слов в SQL
И если вы глянете в БД, то в таблице pupil не найдете колонку name. Отсюда и ошибка.

Решение: в Column укажите name, экранируйте при помощи обратной одинарной кавычки
@Column(name = '"`name`", nullable = false)
        @Getter
        @Setter
        private String name;


Полезный ресурс - https://vladmihalcea.com/escape-sql-reserved-keywo...

Что касается OneToMany & ManyToOne, то рекомендую прочитать эту статью.
https://vladmihalcea.com/the-best-way-to-map-a-one...
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы