如何解决多个嵌套实体上的 Spring JPA 双向关系
我知道过去使用 spring jpa 的双向关系存在多个问题,但我的情况有点不同,因为我使用 3 个具有 2 个关系的实体来实现医疗系统
我有 3 个实体:医生/患者/预约
这是3个实体的代码 请注意所有已实现但在此处省略的 setter、getter 和构造函数
患者班
@Entity
public class resPatient {
@Id
@GeneratedValue( strategy= GenerationType.IDENTITY )
private long code;
private String name;
private String gender;
private String email;
private String mobile;
private int age;
private String notes;
@OnetoMany(mappedBy = "patient")
List<resPackageMembership> memberships;
@OnetoMany(mappedBy = "patient")
List<resAppointment> appointments;
@OnetoMany(fetch = FetchType.LAZY,mappedBy = "patient")
List<resMedImage> medImages;
博士班
@Entity
public class resdoctor {
@Id
@GeneratedValue( strategy= GenerationType.IDENTITY )
private long code;
private String name;
private String mobile;
private String email;
private String gender;
private int age;
private String speciality;
@OnetoMany(mappedBy = "doctor")
List<resAppointment> appointments;
预约班
@Entity
public class resAppointment {
@Id
@GeneratedValue( strategy= GenerationType.IDENTITY )
private long code;
private String speciality;
@Basic
@Temporal(TemporalType.TIMESTAMP)
private Date dateCreated;
@Basic
@Temporal(TemporalType.TIMESTAMP)
private Date datetoVisit;
private String status;
private String notes;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "doctorCode")
private resdoctor doctor;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "patientCode")
private resPatient patient;
我的医疗系统应该工作的方式是,当我让患者使用我的宁静控制器时,我想要所有患者数据,包括他的预约,但这会导致无限循环,因为预约有医生也有预约等等.
我不能使用@JSONIGnorE,因为我想让病人有两个关系,他的约会应该让医生没有约会数组,并且不应该有任何病人数据,因为我已经在病人对象中了
解决方法
作为一般的最佳实践,建议将实体与用于其余控制器的数据传输对象分开。有了 DTO,您就可以更好地控制要在其中包含和序列化哪些数据以避免循环引用。 如果您喜欢查看 https://bootify.io,它会根据您的数据库架构生成 DTO,但您仍然需要定义/构建自定义端点。
,我最近开发了一个名为 beanknife 的注解处理器,它支持从任何类生成 DTO。您需要通过注释进行配置。但是您不需要更改原始类。该库支持在单独的类上进行配置。当然,您可以选择您想要的属性和不需要的属性。您可以通过配置类中的静态方法添加新属性。对于您的问题:
// this will generate a DTO class named "resPatientView".
// You can change this name using genName attribute.
@ViewOf(value=resPatient.class,includePattern = ".*")
public class PatientViewConfigure {
// here tell the processor to automatically convert the property appointments from List<resAppointment> to List<resAppointmentWithoutPatient>.
// resAppointmentWithoutPatient is the generated class configured at the following.
// Note,although at this moment it not exists and your idea think it is an error.
// this code really can be compiled,and after compiled,all will ok.
@OverrideViewProperty("appointments")
private List<resAppointmentWithoutPatient> appointments;
}
// here generated a class named resAppointmentWithoutPatient whick has all properties of resAppointment except patient
@ViewOf(value=resAppointment.class,genName="resAppointmentWithoutPatient",includePattern = ".*",excludes={"patient"})
public class AppointmentWithoutPatientViewConfigure {
// the doctor property will be converted to its dto version which defined by the configure class DoctorWithoutAppointmentsViewConfigure.
@OverrideViewProperty("doctor")
private resDoctorWithoutAppointments doctor;
}
// here we generate a class which has all properties of resDoctor except appointments
@ViewOf(value=resDoctor.class,genName="resDoctorWithoutAppointments",excludes={"appointments"})
public class DoctorWithoutAppointmentsViewConfigure {}
// in you rest controller. return the dto instead of the entities.
resPatient patient = ...
resPatientView dto = resPatientView.read(patient);
List<resPatient> patients = ...
List<resPatientView> dto = resPatientView.read(patients);
最后,类 resPatientView 将具有与 resPatient 相同的形状,除了它的约会没有患者属性并且其医生属性被替换为没有约会属性的版本。
这里有更多examples。 1.10 版本已准备就绪。将修复一些bug并支持spring管理的configure bean。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。