Hibernate 一对多关系级联删除

Posted

技术标签:

【中文标题】Hibernate 一对多关系级联删除【英文标题】:Hibernate One-to-Many relationship cascade delete 【发布时间】:2016-05-03 23:56:35 【问题描述】:

我是 Hibernate 的新手,所以请指导我。

我有 2 个实体公司和员工。一家公司应该有很多员工。

员工休眠映射文件

<hibernate-mapping>
   <class name="com.hibernate.demo.Employees" table="employees">
      <meta attribute="class-description">
         This class contains the employee detail. 
      </meta>
      <id name="empId" type="int" column="emp_id">
         <generator class="native"/>
      </id>
      <property name="empCId" column="emp_cid" type="int"/>
      <property name="empName" column="emp_name" type="string"/>
      <property name="empContact" column="emp_contact" type="int"/>
   </class>
</hibernate-mapping>

公司休眠映射文件

<hibernate-mapping>
   <class name="com.hibernate.demo.Companies" table="companies" >
      <meta attribute="class-description">
         This class contains the companies detail. 
      </meta>
      <id name="compId" type="int" column="comp_id">
         <generator class="native"/>
      </id>
      <set name="employees" cascade="all" >
         <key column="emp_cid"/>
         <one-to-many class="com.hibernate.demo.Employees" />
      </set>
      <property name="compName" column="comp_name" type="string"/>
      <property name="compCity" column="comp_city" type="string"/>
   </class>
</hibernate-mapping>

休眠配置文件

<hibernate-configuration>
   <session-factory>
        <property name="hibernate.dialect">org.hibernate.dialect.mysqlDialect</property>
        <property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property> 
        <property name="hibernate.connection.url">jdbc:mysql://localhost:3306/hibernatedbdemo</property>
        <property name="hibernate.connection.username">root</property>
        <property name="hibernate.connection.password">knowarth</property>
        <property name="show_sql">true</property>       
        <property name="format_sql">true</property>     
        <property name="hbm2ddl.auto">update</property>     

        <mapping resource="employees.hbm.xml"/>
        <mapping resource="companies.hbm.xml"/>
    </session-factory>
</hibernate-configuration>

简单的 POJO 类。

Employees.java

public class Employees 
    public Employees()
    private int empId;
    private int empCId;
    private String empName;
    private int empContact;
    //Getter & Setter

Companies.java

public class Companies 
    public Companies()
    private int compId;
    private String compName;
    private String compCity;
    private Set<Employees> employees;
    //Getter & Setter

我想从公司表中删除公司记录,并且应该删除该公司的所有员工。但我面临的问题是公司记录被所有与该公司相关的员工记录删除。

以下是删除代码

public class CompanyDao 
    Configuration cfg = new Configuration().configure("hibernate.cfg.xml");
    SessionFactory sf = cfg.buildSessionFactory();
    Session session = sf.openSession();
    Companies comp = new Companies();
    Scanner compSc = new Scanner(System.in);

    public void deleteComp()
        session.beginTransaction();
        System.out.println("Enter Company ID to delete it");
        int cmp_id = compSc.nextInt();
        Companies company = new Companies();
        company.setCompId(cmp_id);  
        session.delete(company);        
        session.getTransaction().commit();
        return;
    

【问题讨论】:

这听起来像是 mysql 的那个臭名昭著的外键触发错误。 bugs.mysql.com/bug.php?id=11472 但我认为您的问题与该错误无关 @bmarkham :在我的 mysql 表中,我没有提供任何提供任何主外键关系的信息。我试图通过使用一对多关系来实现它。请让我知道我在哪里做错了。 【参考方案1】:

您可以依赖数据库来级联 DELETE 语句,在这种情况下您需要将映射更改为:

 <set name="employees" cascade="all" inverse="true" >
     <key column="emp_cid" on-delete="cascade" />
     <one-to-many class="com.hibernate.demo.Employees" />
 </set>

如果您不想更改映射,则需要从数据库中获取实体并让 Hibernate 处理子删除:

public void deleteComp()
    session.beginTransaction();
    System.out.println("Enter Company ID to delete it");
    int cmp_id = compSc.nextInt();
    Companies company = session.get(Companies.class, cmp_id); 
    session.delete(company);        
    session.getTransaction().commit();
    return;

【讨论】:

得到错误只有反向一对多关联可以使用 on-delete="cascade": com.hibernate.demo.Companies.employees 然后将其反转并在Employees 映射上添加多对一关联。 我正在使用 Eclipse,它迫使我使用一对多和多对多。它在多对一上给出错误,所以我只是添加 inverse="true" 并解决了我的错误。谢谢。如果出现其他疑问,我会告诉你 @Vlad Mihalcea:你在 Hibernate 上写了很多很棒的东西:在 SO 上的回复以及你的博客。谢谢!

以上是关于Hibernate 一对多关系级联删除的主要内容,如果未能解决你的问题,请参考以下文章

hibernate之一对多,多对一

三大框架 之 Hibernate查询(一对多多对多查询关系)

Hibernate的一对多自关联中的级联删除问题

hibernate中多表映射关系配置

hibernate中多表映射关系配置

hibernate初步2