Некорректно отрабатывает тест
Есть два Entity, первая BaseModel, который содержит id и от него наследуются другие Entity.
@Entity
abstract class BaseModel {
@Id
@Column(name = "id")
@Getter
@GeneratedValue(strategy = GenerationType.AUTO)
private long id;
public BaseModel(long id) {
this.id = id;
}
protected BaseModel() {
}
}
Вторая Entity, Pupil.
@Entity
@Table(name = "pupil")
public final class Pupil extends BaseModel {
@OneToOne
@JoinColumn(name = "pupilID")
private PupilInClassRoom pupilInClassRoom;
@Column(nullable = false)
@Getter
@Setter
private String name;
@Getter
@Setter
@Column(nullable = false)
private String surname;
public Pupil(long id,String name, String surname) {
super(id);
this.name = name;
this.surname = surname;
}
public Pupil() {
}
}
Делаю тест на добавление в таблицу.
@Rollback(value = false)
public Pupil contextLoads() {
Pupil pupil1 = new Pupil();
pupil1.setName("Hello");
pupil1.setSurname("hello");
return pupilRepository.save(pupil1);
}
@Test
public void testCount() {
Pupil pupil = contextLoads();
System.out.println(pupil);
}
Стартую тест и он мне говорит, что поле DISCIPLINE, которые есть в другой Entity(Teacher) не может быть NULL, что верно, но какое отношение это имеет к добавлению Pupil.
NULL not allowed for column "DISCIPLINE"; SQL statement:
insert into base_model (name, pupilid, surname, dtype, id) values (?, ?, ?, 'Pupil', ?) [23502-200]
Другой вариант теста
@Before("contextLoads()")
@Rollback(value = false)
public void contextLoads() {
Pupil pupil1 = new Pupil();
pupil1.setName("Hello");
pupil1.setSurname("hello");
pupilRepository.save(pupil1);
}
@Test
public void testCount() {
System.out.println(pupilRepository.findAll());
}
В данном случае в консоль падает
[]
Хотя должен вывести одного Pupil
Если для филда discipline в Entity Teacher сделать @Column(nullable = true) то все отрабатывает корректно. В консоль падает
com.SchoolJournal.SpringHibernate.model.Pupil@2b625e82
Тест на выборку данных:
@Query(nativeQuery = true, value = "SELECT p.id, p.name, p.surname FROM pupil as p " +
"INNER JOIN pupil_in_class_room as in ON p.id = in.pupilID " +
"INNER JOIN teacher as t ON t.id = in.teacherID " +
"WHERE t.name(:name)")
List<Pupil> findPupilByTeacher(@Param("name") String name);
Ошибка
Schema "T" not found; SQL statement:
Ответы (1 шт):
Это нормальное и ожидаемое поведение, когда для хранения иерархии объектов используется одна таблица (Table per class hierarchy):
There is a limitation of this mapping strategy: columns declared by the subclasses, such as CCTYPE, cannot have NOT NULL constraints.
В этом случае в одной таблице хранятся поля всех наследников (в данном случае класса BaseModel). Там хранятся как поля базового класса, так и поля классов из иерархии. Для того, чтоб понимать, какого именно типа объект хранится в записи используется специальное поле - дискриминатор (в вашем случае dtype). И поля в таком случае не могут иметь ограничения not null, т.к. значения в колонках для полей объекта одного подкласса, скажем поле discipline из Teacher) будут всегда пустыми в записях для другого подкласса, скажем Pupil.
Если это ограничение вам не подходит, то нужно переключиться на другую стратегию хранения иерархии: table per class или joined table.
В первом случае добавьте @Inheritance(strategy = InheritanceType.TABLE_PER_CLASS) к базовому классу.
Во втором случае добавьте @Inheritance(strategy = InheritanceType.JOINED) к базовому классу.