我使用的是spring引导和spring数据,在尝试使用jpa和entitygraph加载实体时遇到了问题。我有一个病人和保险公司。每个病人可以有许多保险,每个保险可以分配给许多病人。我决定使用联接表patientinsurance,因为我需要存储额外的字段,如“active”,以及关系代码(患者可以是该特定保险的成员、配偶或子女)。
使用spring数据存储库,我用entitygraph注解了查找患者的方法,以便在一个查询中准备好该患者的患者保险(和保险)列表。
这是代码(我删除了范围中不必要的部分)
病人类别
@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,cascade = {CascadeType.PERSIST, CascadeType.MERGE, 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;
}
}
}
实施病人服务
@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.
因此,问题似乎是,当我进入患者侧时,我可以毫无问题地循环到他的保险中,但是当我尝试从保险示例开始执行相同的操作时,我无法循环到其患者中,因为他们是懒洋洋地加载的。那么如何让jpa以正确的方式下载完整的图形呢?
暂无答案!
目前还没有任何答案,快来回答吧!