Java 为什么级联持久化在Hibernate中不适用于多对多关系?
请查看以下两个类(实体)Java 为什么级联持久化在Hibernate中不适用于多对多关系?,java,hibernate,orm,many-to-many,cascade,Java,Hibernate,Orm,Many To Many,Cascade,请查看以下两个类(实体)Student和Course 公共班级学生{ ... @多个(级联=级联类型.ALL) @JoinTable(name=“课程\学生”, joinColumns=@JoinColumn(name=“student\u id”), inverseJoinColumns=@JoinColumn(name=“课程id”) ) 私人名单课程; ... } 公共课{ ... @多个(级联=级联类型.ALL) @JoinTable(name=“课程\学生”, joinColumns=
Student
和Course
公共班级学生{
...
@多个(级联=级联类型.ALL)
@JoinTable(name=“课程\学生”,
joinColumns=@JoinColumn(name=“student\u id”),
inverseJoinColumns=@JoinColumn(name=“课程id”)
)
私人名单课程;
...
}
公共课{
...
@多个(级联=级联类型.ALL)
@JoinTable(name=“课程\学生”,
joinColumns=@JoinColumn(name=“课程id”),
inverseJoinColumns=@JoinColumn(name=“student\u id”)
)
私人名单学生;
...
}
驱动程序代码如下所示
试试看{
session.beginTransaction();
课程=新课程(“四弦琴大师班”);
Student student1=新学生(“吉什努”、“M V”、”jishnumv@gmail.com");
学生2=新学生(“Praveen”、“M V”、”praveenmv@gmail.com");
课程。增加(学生1);
课程。增加(学生2);
保存(课程);
session.getTransaction().commit();
}
当我运行这段代码时,我得到以下异常
Exception in thread "main" java.lang.IllegalStateException: org.hibernate.TransientObjectException: object references an unsaved transient instance - save the transient instance before flushing: com.jithin.entity.Student
所以我的怀疑是坚持课程不会坚持相关学生,即使我们在课程课中提到了CascadeType.ALL。那么,为什么级联在多对多的情况下不起作用呢?
注意:在保存课程对象之前,我使用session.save()
保存了两个学生对象。也不例外
@manytomy
关联的拥有方使用@JoinTable
注释@实体
公立班学生{
@ManyToMany(cascade={CascadeType.PERSIST,CascadeType.MERGE})
@JoinTable(name=“课程\学生”,
joinColumns=@JoinColumn(name=“student\u id”),
inverseJoinColumns=@JoinColumn(name=“course\u id”))
私人名单课程;
// ...
}
@实体
公共课{
@ManyToMany(mappedBy=“courses”,cascade={CascadeType.PERSIST,CascadeType.MERGE})
私人名单学生;
// ...
}
课程
实体添加以下方法:公共课{
公立学校学生(学生){
学生。添加(学生);
student.getCourses().add(此);
}
公共无效撤销学生(学生){
学生。移除(学生);
student.getCourses().删除(此);
}
// ...
}
然后你就可以做这样的事情:
课程=新课程(“四弦琴大师班”);
Student student1=新学生(“吉什努”、“M V”、”jishnumv@gmail.com");
学生2=新学生(“Praveen”、“M V”、”praveenmv@gmail.com");
课程。添加学生(学生1);
课程。添加学生(学生2);
保存(课程);
@ManyToMany
关联,将删除
实体状态转换级联是没有意义的,因为它将传播到链接表之外。由于另一端可能被父端上的其他实体引用,因此自动删除可能最终导致ConstraintViolationException
这就是为什么你应该避免使用
cascade=CascadeType.ALL
中的@manytomy
你所说的Nb是什么意思:当我保存学生时,代码也能完美地工作。?我的意思是在保存课程对象之前,我使用session.save()保存了两个学生对象。没有例外。@jithinMV您有课程
内课程
?@SternK噢,对不起,代码编辑不正确。现在已经更新了。谢谢你指出,谢谢你的解释。我试过你提到的代码。但它只是将课程保存到数据库中,但仍然不能通过级联保存课程的相关学生。它应该可以工作。您是否使用了与我在回答中提到的完全相同的映射(包括帮助器方法)?是的。我在浏览同一个问题时发现了一些东西。当我们使用session.save()时,级联发生在hibernate下的save_UPDATE级联类型中。不在JPA之内。因此,要么我们必须添加级联类型。全部并使用session.save(),否则我们必须使用session.persist()。不管怎样,前一个不是一个好的实践,因为正如你所说,它还将包括删除,所以我们可以使用后一个,它也可以工作,也许它取决于hibernate版本。我已经用session.save(course)测试了这个映射,它与Hibernate 5.4.10.Final一起工作