【问题标题】:How to delete a row & all its references from the database through Hibernate?如何通过 Hibernate 从数据库中删除一行及其所有引用?
【发布时间】:2013-08-25 05:53:06
【问题描述】:

我正在使用带有 Java 的 Hibernate 3.0。

我有以下课程。

Teacher.java

private long id;
private String teacherName;
private List<Student> students;
// getter-setter of all

Subject.java

private long id;
private String subjectName;
private List<Student> students;
// getter-setter of all

Student.java

 private long id;
 private String studentName;

// getter-setter of both

Teacher.hbm.xml

<class name="Teacher" table="teacher_master">
    <!--other mappings-->

    <list name="students" cascade="refresh" table="teacher_student_master">
        <key column="teacher_id"/>
        <index column="student_teacher_position" type="integer"/>
        <many-to-many class="Student" column="student_id"/>
    </list>
</class>

Subject.hbm.xml

<class name="Subject" table="subject_master">
    <!--other mappings-->

    <list name="students" cascade="refresh" table="subject_student_master">
        <key column="subject_id"/>
        <index column="student_subject_position" type="integer"/>
        <many-to-many class="Student" column="student_id"/>
    </list>
</class>

Student.hbm.xml 包含 idstudentName 属性的映射。

我面临的问题是:

我通过 Hibernate 从 student_master 中删除了一行。

Student stu = new Student();
stu.setId(1l);
session.delete(stu);
transaction.commit();

但已删除 student (id = 1) 的引用并未从表 teacher_student_mastersubject_student_master 中删除。

我该如何解决这个问题?

注意:如果我可以通过使用 Hibernate 进行某种配置而不是编码和查询触发来解决这个问题,那就太好了。

编辑:我看过这个link。但是在那,它提到我需要做一些编码,首先获取与学生=1 关联的所有教师,然后从学生列表中删除学生=1,然后更新教师。我想避免这种编码。有可能吗?

【问题讨论】:

    标签: java sql sql-server-2008 hibernate hibernate-mapping


    【解决方案1】:

    您可以将@Cascade(org.hibernate.annotations.CascadeType.DELETE_ORPHAN) 用于您想要此行为的列。请参阅this question 了解更多信息。

    或者,由于您通过 XML 使用 Hibernate 配置,请使用 cascade="delete-orphan"。看看this blog post,其中解释了不同类型的级联。

    【讨论】:

    • @RAS 使用的是 XML 映射,而不是注释。如果您仅使用 HBM 映射提供答案会更好。
    • 我已经看到了你提供的两个链接。但是在两个链接中,都提到我需要进行一些编码,例如,首先获取与 student=1 关联的所有教师,然后从学生列表中删除 student=1,然后更新教师。我想避免这种编码。有可能吗?
    • 好吧,假设您有以下表格:学生、教师和课程(链接学生和教师)。通过在 Student 对 Course 的引用上使用 DELETE_ORPHAN,删除 student=1 也将删除与该学生有关系的所有 Courses。您不必手动获取所有课程并删除它们,Hibernate 会为您完成。
    • 我不想删除课程,但要断开学生和课程之间的链接。在第二个链接中,此代码块在那里:/*line 1*/ StockDailyRecord sdr1 = (StockDailyRecord)session.get(StockDailyRecord.class, new Integer(56)); /*line 2*/ StockDailyRecord sdr2 = (StockDailyRecord)session.get(StockDailyRecord.class, new Integer(57)); /*line 3*/ Stock stock = (Stock)session.get(Stock.class, new Integer(2)); /*line 4*/ stock.getStockDailyRecords().remove(sdr1); /*line 5*/ stock.getStockDailyRecords().remove(sdr2); /*line 6*/ session.saveOrUpdate(stock);
    • 我需要的是:/*line 1*/ StockDailyRecord sdr1 = (StockDailyRecord)session.get(StockDailyRecord.class, new Integer(56)); /*line 2*/ StockDailyRecord sdr2 = (StockDailyRecord)session.get(StockDailyRecord.class, new Integer(57)); /*line 3*/ session.delete(sdr1); /*line 4*/ session.delete(sdr2);
    【解决方案2】:

    在两个映射文件中使用cascade="delete" 属性。它可能会解决您的问题。如果你想分配“刷新”然后分配多个属性级联使用;

    【讨论】:

    • 我知道cascade = delete。但据我所知,如果我删除 teacher_master 的记录,它会从 teacher_student_master 中删除记录。我的情况是相反的。我正在从 student_master 中删除记录,而不是从 teacher_master 中删除记录。
    【解决方案3】:

    Hibernate 不会删除行,因为 Student 类不知道这些关系。为此,您应该具有双向关系:@ManyToMany List/Set of Teacher 和 @ManyToMany List/Set of Subject in Student 类

    或者,至少,表teacher_student_master和subject_student_master的外键student_id上的数据库删除级联将删除数据库中的行(我认为第一个解决方案更好)。

    但是,无论如何,您应该遍历学生的科目和教师以删除该学生,即使该行在数据库中被删除,学生对象仍然存在,并且可能会在您的应用程序中引发一些问题。 . 一般来说,在使用 Hibernate 保存之前,先处理好关系(双方)

    双向关系更容易

    for(Teacher teacher: student.teachers) {
        teacher.remove(student);
    }
    
    for(Subject subject: student.subjects) {
        subject.remove(student);
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-11-01
      • 2020-09-29
      • 1970-01-01
      • 1970-01-01
      • 2015-12-03
      • 2014-04-12
      • 2011-06-07
      • 1970-01-01
      相关资源
      最近更新 更多