Hibernate父/子关联。更新父级使子项丢失所有关联对象

时间:2014-09-24 14:38:55

标签: java hibernate

我有以下课程。

public class Employee {
    private int id;
    private String firstName;
    private String lastName;
    private Address address;
    private Employer employer;
}

public class Employer {
    private int id;
    private String name;
    private Set<Employee> employees;
}

public class Address {
    private int id;
}
public class Project{
    private int id;
}

<hibernate-mapping>
    <class name="me.hibernate.basic.xml.Employee" table="EMPLOYEE">
        <id name="id" type="int" column="id">
            <generator class="native" />
        </id>
        <property name="firstName" column="first_name" type="string" />
        <property name="lastName" column="last_name" type="string" />
        <many-to-one name="address" column="address" unique="true" class="me.hibernate.basic.xml.Address"/>
        <set name="projects" cascade="save-update, delete-orphan" sort="natural">
            <key column="employee_proj_id" />
            <one-to-many class="me.hibernate.basic.xml.Project" />
        </set>
        <many-to-one name="employer" column="employer" class="me.hibernate.basic.xml.Employer"/>
    </class>
</hibernate-mapping>



<hibernate-mapping>
    <class name="me.hibernate.basic.xml.Employer" table="EMPLOYER">
        <id name="id" type="int" column="id">
            <generator class="native" />
        </id>
        <property name="name" column="name" type="string" />
        <set name="employees" cascade="save-update, delete-orphan" table="EMPLOYEE">
            <key column="employer"/>
            <one-to-many class="me.hibernate.basic.xml.Employee" />
        </set> 
    </class>
</hibernate-mapping>

<hibernate-mapping>
    <class name="me.hibernate.basic.xml.Address" table="ADDRESS">
        <meta attribute="class-description"> This class contains the address detail. </meta>
        <id name="id" type="int" column="id">
            <generator class="native" />
        </id>
    </class>
</hibernate-mapping>  

  <hibernate-mapping>
        <class name="me.hibernate.basic.xml.Project" table="PROJECT">
            <meta attribute="class-description"> This class contains the project detail. </meta>
            <id name="id" type="int" column="id">
                <generator class="native" />
            </id>
        </class>
    </hibernate-mapping>

在我的应用程序中,我创建了几个Employees并为它们分配了一个地址。并添加一些项目。然后我创建了一个雇主并将所有雇员添加到雇主那里。一旦我添加员工并更新雇主,所有员工都会丢失他们的地址和项目。如何保持延迟加载功能。我不需要设置lazy =“false”。

Employee emp1 = ME.addEmployee("Zara", "Ali");
Employee emp2 = ME.addEmployee("Daisy", "Das");

Address addr1 = ME.addAddress(35, "xxxxxx Street", "XXXXX", "XY7 0ZZ");
Address addr2 = ME.addAddress(42, "xxxxxx Street", "XXXXX", "XY7 7ZZ");
ME.setAddress(emp1.getId(), addr1);
ME.setAddress(emp2.getId(), addr2);

Set<Project> proj = new HashSet<Project>();
proj.add(new Project("NOVA"));
proj.add(new Project("GTA Simplify"));
proj.add(new Project("Jazz"));

ME.addProjects(emp.getId(), proj);
ME.addProjects(emp.getId(), proj);

所有工作到目前为止。

Set<Employee> emps = new HashSet<Employee>();
emps.add(emp1); emps.add(emp2);

//Add existing employees to employer - Many-to-one bidirectional
Employer employer = ME.addEmployer("XYZ");
ME.addEmployees(employer.getId(), emps);

public Integer addEmployees(Integer employerID, Set<Employee> employees) {
 Session session = factory.openSession();
 Transaction tx = null;
    try {
      tx = session.beginTransaction();
      Employer employer = (Employer) session.get(Employer.class,employerID);
      employer.getEmployees().clear();
      employer.getEmployees().addAll(employees);
      session.update(employer);
      tx.commit();
  } catch (HibernateException e) {
     if (tx != null)
     tx.rollback();
     e.printStackTrace();
  } finally {
     session.close();
  }
  return employerID;
}

添加员工后,PROJECT.employee_proj_id和EMPLOYEE.address中的所有外键引用都将丢失。

Hibernate日志:

->Hibernate: update EMPLOYEE set first_name=?, last_name=?, basic=?, address=?, employer=? where id=? 
->Hibernate: update EMPLOYEE set first_name=?, last_name=?, basic=?, address=?, employer=? where id=? 
->Hibernate: update PROJECT set employee_proj_id=null where employee_proj_id=?
 ->Hibernate: update PROJECT set employee_proj_id=null where employee_proj_id=?
->Hibernate: update EMPLOYEE set employer=? where id=? ->Hibernate: update EMPLOYEE set employer=? where id=? 

1 个答案:

答案 0 :(得分:0)

我发现在添加更多员工之前,您正在清理员工,这是所有事情的根本原因。在添加地址,项目,雇主等时,我不确定您在做什么,您无需清除员工。如果您在员工上设置了cascadetype.all,那么保存雇主将更新新添加的员工。

employer.getEmployees().clear();//remove this line.
employer.getEmployees().addAll(employees);