微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

如何使用连接表加载彼此关联@OneToMany 的 2 个实体的完整图

如何解决如何使用连接表加载彼此关联@OneToMany 的 2 个实体的完整图

我正在使用 Spring Boot 和 Spring Data,但在尝试使用 JPA 和 EntityGraph 加载实体时遇到问题。 我有一个患者和保险实体。每个患者可以有多个保险,每个保险可以分配给多个患者。我决定使用联接表 PatientInsurance,因为我需要存储额外的字段,如“活动”,以及关系代码(患者可以是该特定保险的成员、配偶或孩子)。

我使用 Spring Data 存储库注释了该方法以使用 EntityGraph 查找患者,以便在一个查询中准备好该患者的 PatientInsurances(和保险)列表。

这是代码(我把范围内不需要的部分去掉了)

患者班

@Entity
@Table(name = "patient")
public class Patient {

    @NotNull
    @NotEmpty
    @Column(length = 60,nullable = false)
    private String patientFirstName;

    @NotNull
    @NotEmpty
    @Column(length = 60,nullable = false)
    private String patientLastName;

    @OnetoMany(fetch = FetchType.LAZY,mappedBy = "patient",cascade = {CascadeType.PERSIST,CascadeType.MERGE,CascadeType.REFRESH})
    List<PatientInsurance> patientsInsurances = new ArrayList<>();

    public void addPatientInsurance(PatientInsurance patientIns) {
        if (!patientsInsurances.contains(patientIns)) {
            patientsInsurances.add(patientIns);
        }
    }

    //other properties...

保险类


@Entity
@Table(name = "insurance")
public class Insurance {

    @Column(name = "policy_id",length = 20)
    private String policyId;

    @OnetoMany(mappedBy = "insurance",fetch = FetchType.LAZY,CascadeType.REFRESH})
    private List<PatientInsurance> patientsInsurances = new ArrayList<PatientInsurance>();

    public void addPatientInsurance(PatientInsurance patientIns) {
        if (!patientsInsurances.contains(patientIns)) {
            patientsInsurances.add(patientIns);
        }
    }
    
    //other properties

患者和保险之间的连接表的实体(需要一个连接表用于此实体中的额外字段,如 active 和 relCode

@Entity
@IdClass(PatientInsurance.PatientInsurancePK.class)
@Table(name = "patient_insurance")
public class PatientInsurance implements Serializable {

    @Id
    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "patient_id")
    private Patient patient;

    @Id
    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "insurance_id")
    private Insurance insurance;

    @Column(name = "active")
    private boolean active;

    @Column(length = 1)
    private String relCode;


    public PatientInsurance() {
        insurance = new Insurance();
        patient = new Patient();
    }

    public PatientInsurance(Patient p,Insurance i,boolean active,String relCode) {
        this.patient = p;
        this.insurance = i;
        this.active = active;
        this.relCode = relCode;
        p.addPatientInsurance(this);
        i.addPatientInsurance(this);
    }

    public Patient getPatient() {
        return patient;
    }

    public Insurance getInsurance() {
        return insurance;
    }

    public void setInsurance(Insurance insurance) {
        this.insurance = insurance;
        insurance.addPatientInsurance(this);
    }


    public boolean isActive() {
        return active;
    }

    public void setActive(boolean active) {
        this.active = active;
    }

    public void setPatient(Patient patient) {
        this.patient = patient;
        patient.addPatientInsurance(this);
    }

    public String getRelCode() {
        return relCode;
    }

    public void setRelCode(String relCode) {
        this.relCode = relCode;
    }


    static public class PatientInsurancePK implements Serializable {
        protected Patient patient;
        protected Insurance insurance;

        public PatientInsurancePK() {
        }

        public PatientInsurancePK(Patient patient,Insurance insurance) {
            this.patient = patient;
            this.insurance = insurance;
        }

        @Override
        public boolean equals(Object o) {
            if (this == o) return true;
            if (!(o instanceof PatientInsurancePK)) return false;

            PatientInsurancePK that = (PatientInsurancePK) o;

            if (!patient.equals(that.patient)) return false;
            return insurance.equals(that.insurance);
        }

        @Override
        public int hashCode() {
            int result = (patient != null) ? patient.hashCode() : 0;
            result = 31 * result + ((insurance != null) ? insurance.hashCode() : 0);
            return result;
        }
    }
}

PatientService 的实现

@Transactional
@Service("patientService")
public class PatientServiceImpl implements PatientService {

    @Autowired
    PatientRepository patientRepository;

    @Override
    public Optional<Patient> findByIdFull(Long id) {
        Optional<Patient> patient = patientRepository.findById(id);      
        return patient;
    }

    //other methods...

患者资料库

public interface PatientRepository extends JpaRepository<Patient,Long> {

    @EntityGraph(
            attributePaths = {
                    "patientsInsurances","patientsInsurances.patient","patientsInsurances.insurance"},type = EntityGraph.EntityGraphType.LOAD)
    Optional<Patient> findById(Long id);

调用PatientService中方法的一段代码

Optional<Patient> patientOptional = patientService.findByIdFull(p.getId());
if (patientOptional.isPresent()) {
     Patient patient1 = patientOptional.get();
     
     List<PatientInsurance> patientInsurances = patient1.getPatientInsurances();
     PatientInsurances patientInsurance = patientInsurances.get(0);
     Patient patient2 = patientInsurance.getPatient(); //and this is same istance of patient1,it's ok
     Insurance insurance = patientInsurance.getInsurance();
     //here is the problem!!!
     insurance.getPatientInsurances(); 
     //Unable to evaluate the expression Method threw 'org.hibernate.LazyInitializationException' exception.       

所以问题似乎是,当我进入患者侧时,我可以毫无问题地循环到他的 Insurances 中,但是当我尝试从 Insurance 实例开始执行相同操作时,我无法循环到其患者中,因为它们被懒惰地加载. 那么如何让jpa以正确的方式下载全图呢?

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其他元素将获得点击?
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。)
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbcDriver发生异常。为什么?
这是用Java进行XML解析的最佳库。
Java的PriorityQueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么?
如何在Java中聆听按键时移动图像。
Java“Program to an interface”。这是什么意思?