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一起工作