搜索了几个来源,但没有得到确切的场景。仅发布所需的代码...学生实体
class Student {
@OneToMany(mappedBy = "student", cascade = CascadeType.ALL)
private List<Fee> feeList = new ArrayList<>();
public void addFee(Fee fee) {
fee.setStudent(this);
this.feeList.add(fee);
}
}
收费实体
class Fee {
@ManyToOne
private Student student;
}
获取学生并向父实体添加费用
Student student = studentService.findByAdmissionNo(paymentDTO.getAdmissionNo());
Fee f = new Fee();
s.addFee(f);
创建并填充对象后,我使用 jpa 存储库来保存学生(家长)实体。
//fee reference
Fee fee = new Fee(paymentDTO.getAmount(), paymentDTO.getDiscount(), dateOfPayment, paymentDTO.getTransactionID(), paymentDTO.getAcademicYear());
student.addFee(fee);
studentService.save(student);
能够查看数据库中创建的学生和费用记录。 在上述提交之后,学生实体将填充来自 DB 的学生的费用记录,这是预期的。但是我们在保存之前添加到学生实体的参考费用尚未使用作为上述提交的一部分填充的Id进行更新,它仍然为0(默认值)。 我想获取作为上述提交的一部分创建的费用 ID。我们可以从学生实体获取 ID,但问题是学生实体已从数据库填充了该学生的多个费用记录,因此不知道哪些记录是作为当前事务的一部分创建的。
请帮忙。
猜猜您正在使用
JpaRepository
中的studentService
来拯救学生?
因为
JpaRepository
将在学生实例上调用merge()
,然后在费用实例上级联调用merge()
以将数据库记录插入到费用表中,事情是
Fee mergedFee = entityManager.merge(fee);
不会更新输入费用实例的 Id,而只会更新返回的费用实例的 Id。由于您现在在学生实例上使用
JpaRepository
,因此它始终会按设计返回学生实例,您可以永远不会得到 merge(fee)
返回的费用实例
如果你改为使用
feeRepository
来节省费用应该可以:
Student student = studentService.findByAdmissionNo(xxx);
Fee fee = new Fee();
s.addFee(fee);
feeRepository.save(fee);
或者使用 hibernate 特定的
saveOrUpdate()
也应该可以:
Student student = studentService.findByAdmissionNo(xxx);
Fee fee = new Fee();
s.addFee(fee);
Session session = entityManager.unwrap(Session.class);
session.saveOrUpddate(student);
或者直接保存
fee
而不是通过学生,这是我更喜欢的方式:
Student student studentService.findByAdmissionNo(xxx);
Fee fee = new Fee();
fee.paidBy(student); //just a setter to set fee.student
feeRepository.save(fee);