gpt4 book ai didi

java - Hibernate 在更新时添加 OneToMany 实体两次

转载 作者:行者123 更新时间:2023-12-02 03:43:45 25 4
gpt4 key购买 nike

我在更新实体时遇到问题。这是我带注释的模型:(注意:还有很多我认为与问题无关的字段)

员工

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

我得到的行为:

当工资为 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=?

最佳答案

这是 N+1 problem 的症状。我通过在我的 List 实体上使用 @Fetch(FetchMode.SUBSELECT) 注释解决了这个问题。或者,您可以使用 Set 来代替,尽管这有其他副作用。

关于java - Hibernate 在更新时添加 OneToMany 实体两次,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36532460/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com