2014-09-24 125 views
0

我有以下课程。休眠父/子关联。更新父母让孩子失去了所有相关的对象

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> 

在我的应用程序中,我创建了几个员工并为他们分配一个地址。并添加一些项目。然后,我创建一个雇主,并将所有员工添加到雇主。一旦我添加员工并更新雇主,所有员工都会失去他们的地址和项目。我怎样才能做到这一点,保持延迟加载功能。我不需要设置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=? 
+0

我可以看到下面的sql查询被触发。 - > Hibernate:更新EMPLOYEE set first_name =?,last_name =?,basic =?,address =?,employer =?其中id =? - > Hibernate:更新EMPLOYEE set first_name =?,last_name =?,basic =?,address =?,employer =?其中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:更新EMPLOYEE set employer =?其中id =? - > Hibernate:更新EMPLOYEE set employer =?其中id =? – Rasika 2014-09-24 14:43:41

+0

如果我将雇主设置为员工,而不是将雇员集合添加到雇主,则工作正常。两种情况都是hibernate更新员工记录。但是,只有当雇员加入雇主时,员工才会失去他们的项目。 – Rasika 2014-09-24 16:29:52

回答

0

我看你增加更多的员工面前,这是一切的根源,你是清理员工。我不确定你在添加地址,项目,雇主等时做了什么,你不需要清除员工。如果您在员工身上设置了cascadetype.all,则保存雇主将更新新添加的员工。

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