java 一对多关系在我的Sping Boot 应用程序中与Postgres数据库不起作用

dm7nw8vv  于 2023-10-14  发布在  Java
关注(0)|答案(1)|浏览(97)

我试图在我的Sping Boot 应用程序中使用Postgres数据库的Joins。一些实体具有一对一关系,而一些实体具有多个一对多关系。Entity类和runner函数的代码如下所示,以供参考。我还没有展示DevicesRequired和Benefit的Entity类。它们遵循与DevicesReceived相同的结构,在@JoinColumn中具有相同的“personal_details_id_no”字段,该字段也存在于我的DB中的每个表中。我的问题是,当我执行我的“saveData”运行函数时,我的“所有者”表中带有@ManyToOne注解的“personal_details_id_no”总是空的。但是,@OneToOne字段(即,address_id_no)已正确填充,不会出现给予任何问题。
我已经尝试过查看文档,我正确地遵循了这些步骤,但问题仍然存在。任何帮助将不胜感激。
注意:我使用liquibase创建表格。我已经在每个所有者表中创建了“personal_details_id_no”。

@Entity
@Table(name="personal_details")
@Data
@AllArgsConstructor
@NoArgsConstructor
@Builder(toBuilder = true)
@JsonNaming(PropertyNamingStrategy.SnakeCaseStrategy.class)
public class PersonalDetail extends Auditable<String> implements Serializable {
    private static final long serialVersionUID = 1L;

    @Id
    private String idNo;

    private String gender;

    private String name;

    // For Address
    @OneToOne(cascade = CascadeType.ALL)
    @JoinColumn(name = "address_id_no", referencedColumnName = "idNo")
    private Address address;

    // For Devices Received
    @JsonManagedReference
    @OneToMany(fetch = FetchType.LAZY, mappedBy = "personalDetail", cascade = CascadeType.ALL)
    private List<DevicesReceived> devicesReceivedList;

    // For Devices Required
    @JsonManagedReference
    @OneToMany(fetch = FetchType.LAZY, mappedBy = "personalDetail", cascade = CascadeType.ALL)
    private List<DevicesRequired> devicesRequiredList;

    // For Benefits
    @JsonManagedReference
    @OneToMany(fetch = FetchType.LAZY, mappedBy = "personalDetail", cascade = CascadeType.ALL)
    private List<Benefit> benefitList;
}
@Entity
@Table(name = "address")
@Data
@AllArgsConstructor
@NoArgsConstructor
@Builder(toBuilder = true)
@JsonNaming(PropertyNamingStrategy.SnakeCaseStrategy.class)
public class Address extends Auditable<String> implements Serializable {
    private static final long serialVersionUID = 1L;
    
    @Id
    private String idNo;

    private String address;
}
@Entity
@Table(name="devices_received")
@Data
@AllArgsConstructor
@NoArgsConstructor
@Builder(toBuilder = true)
@JsonNaming(PropertyNamingStrategy.SnakeCaseStrategy.class)
public class DevicesReceived extends Auditable<String> implements Serializable {
    private static final long serialVersionUID = 1L;

    @Id
    @GeneratedValue(strategy= GenerationType.IDENTITY)
    private Integer id;

    private String idNo;

    private String device;

    @JsonBackReference
    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "personal_details_id_no", nullable = false)
    private PersonalDetail personalDetail;
}
// Runner Function
public void saveData(DetailsResponseDTO detailsResponseDTO) throws Exception {
    PersonalDetail personalDetail = new PersonalDetail().toBuilder()
            .idNo(detailsResponseDTO.getData().idNo())
            .name(detailsResponseDTO.getData().getName())
            .address(detailsResponseDTO.getData().getAddress())
            .devicesReceivedList(detailsResponseDTO.getData().getDevicesReceived())
            .devicesRequiredList(detailsResponseDTO.getData().getDevicesRequired())
            .benefitList(detailsResponseDTO.getData().getBenefits())
            .build();
    try {
        personalDetailRepository.save(personalDetail);
    } catch (Exception e) {
        System.out.println("Error while saving personalDetail Details: " + personalDetail + ", with Exception: " + e.toString());
        throw e;
    }
}
up9lanfz

up9lanfz1#

我想出了答案。似乎必须在PersonalDetail类中显式定义setter函数,以建立父实体和子实体之间的关系。类似下面的函数,需要显式调用而不是使用Builder。

public void setDevicesReceivedList(List<DevicesReceived> devicesReceivedList) {
    for(DevicesReceived devicesReceived : devicesReceivedList) {
        devicesReceived.setPersonalDetail(this);
        this.devicesReceivedList.add(devicesReceived);
    }
}

这个setter必须在runner函数中显式调用,即。

personalDetail.setDevicesReceivedList(detailsResponseDTO.getData().getDevicesReceived());

相关问题