【问题标题】:Spring JPA bidirectional relation on multiple nested entities多个嵌套实体上的 Spring JPA 双向关系
【发布时间】:2020-12-27 13:36:58
【问题描述】:

我知道过去有多个关于使用 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;

我的医疗系统应该工作的方式是,当我让病人使用我的 restful 控制器时,我想要所有的病人数据,包括他的预约,但这会导致一个无限循环,因为预约的医生也有预约等等.

我不能使用@JSONIGNORE,因为我希望有两个关系让病人预约,这应该让医生没有预约数组,并且不应该有任何病人数据,因为我已经在病人对象中

【问题讨论】:

  • 我得到的对象是 { "code": 1, "name": "ahmed ali mohamed", "age": 22, "notes": "high blood pressure", "memberships" : [], "约会": [ { "code": 1, "speciality": "laser", "doctor": { "code": 3, "name": "mohamed kalafalla", "mobile": "012 ", "gender": "male", "age": 22, "speciality": "heart", "appointments": [ {

标签: spring spring-boot hibernate spring-data-jpa spring-data


【解决方案1】:

作为一般的最佳实践,建议将实体与用于其余控制器的数据传输对象分开。使用 DTO,您可以更好地控制要在其中包含和序列化哪些数据,以避免循环引用。 如果您喜欢查看https://bootify.io,它会根据您的数据库架构生成 DTO,但您仍然需要定义/构建自定义端点。

【讨论】:

    【解决方案2】:

    我最近开发了一个名为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", includePattern = ".*", 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 版本已准备就绪。将修复一些错误并支持由spring管理的configure bean。

    【讨论】:

    • 伟大的工作!谢谢
    猜你喜欢
    • 1970-01-01
    • 2023-03-31
    • 2019-01-24
    • 2019-04-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-04-07
    • 2016-05-02
    相关资源
    最近更新 更多