У меня есть класс Group
, который может содержать несколько проектов:
@Entity
@Table(name = "groups")
public class Group {
@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE)
private Long id;
private Integer version;
@OneToMany(
mappedBy = "group",
fetch = FetchType.LAZY,
cascade = {
CascadeType.PERSIST,
CascadeType.MERGE
})
private List<Project> projects;
public void addProject(Project project) {
if (projects == null) {
projects = new ArrayList<>();
}
this.projects.add(project);
project.setGroup(this);
}
public void removeProject(Project project) {
if (projects == null || projects.size() == 0) {
return;
}
this.projects.remove(project);
project.setGroup(null);
}
}
и класс Project
:
@Entity
public class Project {
@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE)
private Long id;
private String name;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn
private Group group;
}
Приведенный ниже код выдаст ошибку при запускепотому что каскадный тип не установлен в Project
классе:
Group group = new Group(123);
Project project = new Project("projectName");
group.addProject(project);
projectRepo.save(project);
java.lang.IllegalStateException: org.hibernate.TransientPropertyValueException: объект ссылается на несохраненный временный экземпляр - сохраните временный экземпляр перед сбросом.
Но когда я запускаю тот же код в тестовом методе, он проходит!И группа, и проект были сохранены.Вот мой конфиг тестового класса:
@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = ApplicationLauncher.class)
В тестовом методе нет никакой специальной аннотации, кроме @Test.Когда я его запускаю, hibernate генерирует 3 SQL-оператора:
- Один для вставки проекта с fk для группы, установленной в ноль
- Один для вставки группы
- Один дляобновите проект fk для ссылки на вставленную группу.
База данных H2 использовалась как в тесте, так и при запуске приложения.
В чем здесь магия?