【问题标题】:Hibernate: Many to many deletion deleting entire table休眠:多对多删除删除整个表
【发布时间】:2014-02-28 04:16:55
【问题描述】:

我通过实体AppointmentRequestDoctorPatient 之间建立了多对多关系。但是,当我删除 1 个 Doctor 时,每个通过 AppointmentRequest 表关联的 DoctorPatient 都会被删除。

这是我的代码:

医生

public class Doctor implements Person {

    private List<AppointmentRequest> appointmentRequests = new ArrayList<AppointmentRequest>();

    @OneToMany(mappedBy="doctor", targetEntity = AppointmentRequest.class, 
             fetch=FetchType.EAGER, cascade= CascadeType.ALL) 
    public List<AppointmentRequest> getAppointmentRequests() {
        return this.appointmentRequests;
    }

}

患者

public class Patient implements Person {

   private List<AppointmentRequest> appointmentRequests = new ArrayList<AppointmentRequest>();

   @OneToMany(mappedBy="patient", targetEntity = AppointmentRequest.class, 
         fetch=FetchType.EAGER, cascade= CascadeType.ALL) 
   public List<AppointmentRequest> getAppointmentRequests() {
       return this.appointmentRequests;
   }

}

约会请求

public class AppointmentRequest {

   private Doctor doctor;
   private Patient patient;

   @ManyToOne (fetch = FetchType.EAGER, cascade= CascadeType.ALL) 
   @JoinColumn(name="doctor_id") 
   public Doctor getDoctor() {
       return doctor;
   }

   @ManyToOne (fetch = FetchType.EAGER, cascade= CascadeType.ALL) 
   @JoinColumn(name="patient_id") 
   public Patient getPatient() {
       return patient;
   }
}

医生删除代码

public void deleteDoctor(String doctor_name) {
    Session session = sessionFactory.openSession();
    Doctor doctor = new Doctor();
    try {
        session.beginTransaction();
        Query query = session.getNamedQuery("Doctor.findByName");
        query.setString("name", doctor_name);
        doctor = (Doctor) query.uniqueResult();
        if(doctor == null) {
            throw new NullPointerException();
        }
        List<AppointmentRequest> appointments = doctor.getAppointmentRequests();
        for(AppointmentRequest appointment:appointments) {
            appointment.setDoctor(null);
        }
        session.delete(doctor);
        session.getTransaction().commit();
    }
    finally {
        session.close();
    }
}

【问题讨论】:

  • 您在集合上设置了 cascade.all。这将删除所有相关的内容。就像一个涟漪效应,如果删除了父项,所有的子子项都会被删除。
  • 您的多对多映射有误。请看这个mkyong.com/hibernate/…
  • 为什么多对多映射错误。它工作得很好,我昨晚实际上实现了这个解决方案,它和我的解决方案做同样的事情。你能告诉我那个解决方案与我的相比有什么好处吗?另外,你是对的,级联不应该设置为全部。
  • 我昨晚真的评论了那篇文章。我想知道使用该解决方案与这个解决方案相比的好处。

标签: java eclipse hibernate jpa


【解决方案1】:

ManyToMany 与连接表的关系中,连接表的存在只是为了创建关系。当关系被破坏/删除时休眠 将自动更新/删除与表中该关系对应的行条目。连接表没有等效的实体定义。换句话说 连接表中的行本身并不代表实体。它没有身份,不能被其他实体共享/引用。但是,在您的情况下,您建模的方式是 您已经创建了一个单独的实体AppointmentRequest,它是可共享/可引用的并封装了关系。这种设计通常是在除了两个相关实体之外,您还有一些其他属性要存储时完成,例如创建日期、创建者等。然后您可以要求实体说明此关系是何时创建的或由谁创建的。所以你需要问的问题是你是否只想要一个many-to-many 关系或者你的关系本身就是一个实体。

【讨论】:

  • 是的,我的 JOIN 表特别需要成为一个实体。我在其中存储了我在示例代码中遗漏的其他属性。我想我应该只分享我的问题所必需的细节
猜你喜欢
  • 2011-02-13
  • 1970-01-01
  • 1970-01-01
  • 2012-09-04
  • 1970-01-01
  • 1970-01-01
  • 2013-02-15
  • 1970-01-01
相关资源
最近更新 更多