2016-04-10 3 views
0

У меня проблемы с обновлением объекта. Вот мои аннотированные модели: (обратите внимание: Есть много других полей, которые я думаю, не имеют никакого отношения к проблеме)Hibernate добавляет OneToMany Entity при обновлении

Сотрудник

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

Paycheck

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

Однако, когда я добавляю вторую зарплату работника, предприятие работника дублируется. В итоге я получаю два сотрудника в базе данных со всеми теми же свойствами, включая «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

Это связано с тем, что спящий режим хранит другую сущность в своей памяти, а когда вы вызываете 'update', hibernate очищает все сущности в памяти, заставляя его обновлять и другое. –

ответ

1

Это симптом N+1 problem. Я работал над этой проблемой, используя аннотацию @Fetch(FetchMode.SUBSELECT) на моих объектах List. В качестве альтернативы вместо этого вы можете использовать Set, хотя это имеет и другие побочные эффекты.

+1

Это исправлено! Я не ожидал такого простого решения. Благодарю. – Safari137