@OneToOne 入门

2022-03-02  本文已影响0人  lz做过前端

几个问题

@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
@EqualsAndHashCode(callSuper = false)
@Entity(name = "testReport")
@EntityListeners(AuditingEntityListener.class)
public class Report extends BaseUUID1AuditingEntity implements Serializable {

    @Column(length = 50)
    private String name;

    @Column
    private Integer size;

    @OneToOne
    private ReportDay reportDay;
}
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
@EqualsAndHashCode(callSuper = false)
@Entity(name = "testReportDay")
@EntityListeners(AuditingEntityListener.class)
public class ReportDay extends BaseUUID1AuditingEntity implements Serializable {

    @Column(length = 50)
    private String dayName;

    @Column
    private Integer daySize;

    @OneToOne
    @JoinColumn(name = "report_id", nullable = false)
    private Report report;
}

级联保存操作

// ReportDay
@OneToOne
@JoinColumn(name = "report_id", nullable = false)
private Report report;

// ======== service ===========
val reportDayModel = model.getReportDay();
ReportDay reportDay = null;
Report report = null;
// =======方式1=======
report = Report.builder()
        .name(model.getName())
        .size(model.getSize())
//      .reportDay(reportDay)
        .build();
reportDay = ReportDay.builder()
        .dayName(reportDayModel.getDayName())
        .daySize(reportDayModel.getDaySize())
        .report(report)
        .build();
// reportRepository.save(report);
reportDayRepository.save(reportDay);
// =========方式2========
reportDay = ReportDay.builder()
        .dayName(reportDayModel.getDayName())
        .daySize(reportDayModel.getDaySize())
//        .report(report)
        .build();
report = Report.builder()
        .name(model.getName())
        .size(model.getSize())
        .reportDay(reportDay)
        .build();
// reportDay.setReport(report);
reportRepository.save(report);
// reportDayRepository.save(reportDay);

当两边只使用@OneToOne会创建表,并且会建外键,保存会报错,说明@JoinColumn只是控制,不是说没有就不增加字段
ReportDay增加@JoinColumn配置,保存报错:Not-null property references a transient value - transient instance must be saved before current operation
Report增加@OneToOne(mappedBy = "report"),仍报上面的错,但是我们发现Report所在的表没有report_day_id字段了,已经委托给ReportDay管理关系了,双向关联时,需要配置它,否则数据库表会多生成一个外键关联,当做级联新增PERSIST时,会为空
Report增加@OneToOne(mappedBy = "report", cascade = CascadeType.PERSIST)保存失败,需要在保存之前reportDay.setReport(report);
ReportDay增加@OneToOne(cascade = CascadeType.PERSIST) ReportDay级联Report保存成功,说明cascade配置在哪个类上,该类save时,级联保存配置在该类下的JPA。
小结:级联可以在两边save,但是如果在mappedBy所在的JPA上级联保存,需要关联实体做双向set。而在委托JPA上做级联保存,则只需要将被委托JPA set 到委托JPA上即可,这也符合委托的含义(被委托JPA上的委托JPA在数据库上不存在,只是JPA层面的关系)

级联删除在委托方可以删除吗?被委托方删除可以理解
orphanRemoval = true 与 级联删除

cascade

CascadeType.PERSIST

上一篇下一篇

猜你喜欢

热点阅读