2016-04-10 8 views
0

エンティティの更新に問題があります。ここに私の注釈付きのモデルは以下のとおりです(注:私は問題とは無関係だと思うより多くのフィールドがある)更新時にOneToManyエンティティを2度追加すると

従業員

@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; 
} 

マイDAOの更新方法:

@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=? 

ただし、従業員に2番目の給与を追加すると、従業員エンティティが複製されます。私は 'id'を含むすべての同じプロパティを持つデータベースに2人の従業員で終わります。また、両方の従業員には、同じ2つの給与が添付されています。メソッドが実行された後、以下が記録されます。

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

関連する問題