2016-04-10 56 views
0

我在更新實體時遇到問題。這裏是我的註解模型:(注:還有更多的領域,我認爲是無關的問題)Hibernate在更新時添加OneToMany實體兩次

員工

@Entity 
public class Employee { 
    @Id 
    @GeneratedValue(strategy = GenerationType.AUTO) 
    private int id; 

    @OneToMany(cascade = CascadeType.ALL, mappedBy = "employee", fetch = FetchType.EAGER) 
    private List<Paycheck> paychecks; 

    // Note: this method does not ever seem to be called 
    @Override 
    public boolean equals(Object o) { 
     System.out.printf("\n\n\nEquals requested!\n\n\n"); 

     if (o == null || !(o instanceof Employee)) { 
      System.out.printf("\n\n\nNot equal! 1\n\n\n"); 
      return false; 
     } 

     Employee other = (Employee) o; 

     if (id == other.getId()) { 
      System.out.printf("\n\n\nEqual! id = id\n\n\n"); 
      return true; 
     } 

     // equivalence by id 
     return id == other.getId(); 
    } 

    @Override 
    public int hashCode() { 
     final int prime = 31; 
     int result = 1; 
     result = prime * result + (id^(id >>> 32)); 
     return result; 
    } 
} 

薪水

@Entity 
public class Paycheck { 
    @Id 
    @GeneratedValue(strategy = GenerationType.AUTO) 
    private int id; 


    @ManyToOne(cascade = CascadeType.ALL, fetch = FetchType.EAGER) 
    private Employee employee; 
} 

吾道更新方法:

@Override 
public void update(T item) { 
    Session session = sessionFactory.getCurrentSession(); 

    session.beginTransaction(); 
    session.saveOrUpdate(item); 
    session.getTransaction().commit(); 
} 

而服務方式:

public List<Paycheck> executePayroll(List<Employee> employees) { 
    List<Paycheck> paychecks = new ArrayList<>(); 

    for(Employee employee : employees) { 
     Paycheck paycheck = engine.processPay(employee, employee.getCurrentHours()); 
     paycheck.setEmployeeId(employee.getId()); 
     paycheck.setEmployee(employee); 
     paycheck.setDate(today); 
     paychecks.add(paycheck); 
     employee.setCurrentHours(0); 

     employee.getPaychecks().add(paycheck); 

     employeeRepository.update(employee); 
    } 

    return paychecks; 
} 

的bahavior我越來越:

當有0領工資,並添加薪水,員工不重複。我得到以下記錄:

Hibernate: call next value for hibernate_sequence 

Hibernate: insert into Paycheck (date, employee_id, employeeId, employerFederalUnemploymentTax, employerMedicareTax, employerSocialSecurityTax, employerStateUnemploymentTax, federalWithholdingTax, grossAmount, medicareWithholdingTax, netAmount, socialSecurityWithholdingTax, stateWithholdingTax, id) values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) 

Hibernate: update Employee set address=?, city=?, currentHours=?, dateOfBirth=?, email=?, federalExemptions=?, firstName=?, isMarried=?, lastName=?, payRate=?, phoneNumber=?, socialSecurityNumber=?, state=?, stateExemptions=?, zipcode=? where id=? 

但是,當我向員工添加第二個薪水時,僱員實體被複制。我最終在數據庫中擁有所有相同屬性的兩名員工,其中包括'id'。此外,兩名僱員都有兩個相同的薪水。方法運行後記錄以下內容:

Hibernate: call next value for hibernate_sequence 

Hibernate: insert into Paycheck (date, employee_id, employeeId, employerFederalUnemploymentTax, employerMedicareTax, employerSocialSecurityTax, employerStateUnemploymentTax, federalWithholdingTax, grossAmount, medicareWithholdingTax, netAmount, socialSecurityWithholdingTax, stateWithholdingTax, id) values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) 

Hibernate: update Employee set address=?, city=?, currentHours=?, dateOfBirth=?, email=?, federalExemptions=?, firstName=?, isMarried=?, lastName=?, payRate=?, phoneNumber=?, socialSecurityNumber=?, state=?, stateExemptions=?, zipcode=? where id=? 

Hibernate: update Paycheck set date=?, employee_id=?, employeeId=?, employerFederalUnemploymentTax=?, employerMedicareTax=?, employerSocialSecurityTax=?, employerStateUnemploymentTax=?, federalWithholdingTax=?, grossAmount=?, medicareWithholdingTax=?, netAmount=?, socialSecurityWithholdingTax=?, stateWithholdingTax=? where id=? 
+0

這是因爲hibernate將其他實體保存在內存中,當您調用update時,hibernate將刷新內存中的所有實體,導致它更新另一個實體。 –

回答

1

這是N+1 problem的一種症狀。我已在我的List實體上使用@Fetch(FetchMode.SUBSELECT)註釋解決了此問題。或者,您也可以使用Set,儘管這有其他副作用。

+1

修好了!我並不期待這樣一個簡單的解決方案。謝謝。 – Safari137

相關問題