jpa 如何通过父实体保存后获取子实体id

50few1ms  于 2023-10-19  发布在  其他
关注(0)|答案(1)|浏览(150)

搜索了几个来源,但没有得到确切的情况。仅发布所需代码...学生实体

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中创建。在上面的提交之后,学生实体得到了来自DB的学生的费用报告,这是预期的。但是我们在保存之前添加到学生实体的参考费没有更新,Id作为上述提交的一部分填充,它仍然是0(默认值)。我想获取作为上述提交的一部分创建的费用ID。我们可以从student实体中获取id,但问题是student实体已经从DB中填充了该学生的多个费用记录,因此不知道哪些记录是作为当前事务的一部分创建的。
请帮帮我

cig3rfwq

cig3rfwq1#

猜猜你是在用studentService中的JpaRepository来保存一个学生?
因为JpaRepository将在一个student示例上调用merge(),然后在一个fee示例上级联调用merge(),以将一条DB记录插入到fee表中,事情是这样的:

Fee mergedFee = entityManager.merge(fee);

不会更新输入的fee示例的Id,而只会更新返回的fee示例的Id。由于您现在在student示例上使用JpaRepository,因此它将始终返回一个student示例,并且您永远无法获得merge(fee)返回的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);

相关问题