美文网首页
@OneToOne 入门

@OneToOne 入门

作者: lz做过前端 | 来源:发表于2022-03-02 09:55 被阅读0次

    几个问题

    • 什么是级联操作?
    @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

    相关文章

      网友评论

          本文标题:@OneToOne 入门

          本文链接:https://www.haomeiwen.com/subject/qivezltx.html