Spring OneToMany 与复合键的关系与另一个具有复合键的关系

Posted

技术标签:

【中文标题】Spring OneToMany 与复合键的关系与另一个具有复合键的关系【英文标题】:Spring OneToMany relation with composite key to another with a composite key 【发布时间】:2017-01-21 19:18:03 【问题描述】:

我想在 2 个类(章节和相机)之间建立多对一关系。一个章节对象包含许多相机对象。

问题是我的父类(章节)已经有一个复合键。

章节复合键:

@Embeddable
public class ChapterKey implements Serializable 

@Column(name = "Chapter_ID", nullable = false)
private int chapterID;

@Column(name = "Operation_FK", nullable = false)
private int operationFK;

章节类:

@Entity
public class Chapter implements Serializable

  private static final long serialVersionUID = 1L;

  @EmbeddedId
  private ChapterKey chapterKey;

  @Column(name="Chapter_Name")
  private String chapterName;

  @Column(name="Chapter_Description")
  private String chapterDescription;

  @Column(name="Chapter_View_Range")
  private int chapterViewRangeInterval;

  @Column(name="Chapter_Video_Length")
  private int chapterVideoLength;
 

相机键:

 @Embeddable
 public class CameraKey implements Serializable 

  @Column(name = "Camera_ID", nullable = false)
  private int cameraID;

  @Column(name = "Chapter_FK", nullable = false)
  private int chapterFK;

  @Column(name = "Operation_FK", nullable = false)
  private int operationFK;

相机类:

@Entity
public class Camera implements Serializable

  private static final long serialVersionUID = 1L;

  @EmbeddedId
  private CameraKey cameraKey;

  @Column(name="Camera_Description")
  private String cameraDescription;

  @Column(name="Camera_Usage")
  private int cameraUsage;

  @Column(name="Video_URL")
  private String videoURL;

我的问题是,我如何在这两个类之间建立 OneToMany 关系?

【问题讨论】:

【参考方案1】:

此答案适用于章节侧pk(Chapter_ID, Operation_FK) 和相机侧pk(camera_id,chapter_fk,operation_fk)

ER 如下。

Chapter.class 是

@Entity
public class Chapter implements Serializable 

    private static final long serialVersionUID = 1L;
    @EmbeddedId
    protected ChapterPK chapterPK;
    @Basic(optional = false)
    @Column(name = "chapter_name", nullable = false, length = 12)
    private String chapterName;
    @Basic(optional = false)
    @Column(name = "chapter_description", nullable = false, length = 12)
    private String chapterDescription;
    @Basic(optional = false)
    @Column(name = "chapter_Vvew_range", nullable = false)
    private int chapterVvewrange;
    @Basic(optional = false)
    @Column(name = "chapter_video_length", nullable = false)
    private int chapterVideoLength;
    @OneToMany(cascade = CascadeType.ALL, mappedBy = "chapter")
    private Collection<Camera> cameraCollection;
    @OneToMany(cascade = CascadeType.ALL, mappedBy = "chapter1")
    private Collection<Camera> cameraCollection1;



ChapterPK.class

@Embeddable
public class ChapterPK implements Serializable 

    @Basic(optional = false)
    @Column(name = "chapter_id", nullable = false)
    private int chapterId;
    @Basic(optional = false)
    @Column(name = "operation_fk", nullable = false)
    private int operationFk;




相机类

@Entity
public class Camera implements Serializable 

    private static final long serialVersionUID = 1L;
    @EmbeddedId
    protected CameraPK cameraPK;

    @Basic(optional = false)
    @Column(name = "camera_description", nullable = false, length = 12)
    private String cameraDescription;

    @Basic(optional = false)
    @Column(name = "camera_usage", nullable = false)
    private int cameraUsage;

    @Basic(optional = false)
    @Column(name = "video_url", nullable = false)
    private int videoUrl;

    @JoinColumn(name = "chapter_fk", referencedColumnName = "chapter_id", nullable = false, insertable = false, updatable = false)
    @ManyToOne(optional = false)
    private Chapter chapter;

    @JoinColumn(name = "operation_fk", referencedColumnName = "operation_fk", nullable = false, insertable = false, updatable = false)
    @ManyToOne(optional = false)
    private Chapter chapter1;




CameraPK.class

@Embeddable
public class CameraPK implements Serializable 

    @Basic(optional = false)
    @Column(name = "camera_id", nullable = false)
    private int cameraId;
    @Basic(optional = false)
    @Column(name = "chapter_fk", nullable = false)
    private int chapterFk;
    @Basic(optional = false)
    @Column(name = "operation_fk", nullable = false)
    private int operationFk;




这里双方都有两种方式绑定。

【讨论】:

这个有两个复合键。与另一个答案不同。你能建议你得到正确的答案吗?【参考方案2】:

这是pk(camera_id)pk(chapter_id,operation_fk) 问题的ER

这是一个章节类。

    @Entity
public class Camera implements Serializable 

    private static final long serialVersionUID = 1L;
    @Id
    @Basic(optional = false)
    @Column(name = "camera_id", nullable = false)
    private Integer cameraId;

    @Basic(optional = false)
    @Column(name = "camera_description", nullable = false, length = 12)
    private String cameraDescription;

    @Basic(optional = false)
    @Column(name = "camera_usage", nullable = false)
    private int cameraUsage;

    @Basic(optional = false)
    @Column(name = "video_url", nullable = false)
    private int videoUrl;

    @JoinColumn(name = "chapter_fk", referencedColumnName = "chapter_id", nullable = false)
    @ManyToOne(optional = false, fetch = FetchType.EAGER)
    private Chapter chapterFk;

    @JoinColumn(name = "operation_fk", referencedColumnName = "operation_fk", nullable = false)
    @ManyToOne(optional = false, fetch = FetchType.EAGER)
    private Chapter operationFk;  


这是 ChapterPK.class 定义章节类的主键。它有复合主键。

    @Embeddable
public class ChapterPK implements Serializable 

    @Basic(optional = false)
    @Column(name = "chapter_id", nullable = false)
    private int chapterId;

    @Basic(optional = false)
    @Column(name = "operation_fk", nullable = false)
    private int operationFk;


终于camera.class

@Entity
public class Chapter implements Serializable 

    private static final long serialVersionUID = 1L;
    @EmbeddedId
    protected ChapterPK chapterPK;
    @Basic(optional = false)

    @Column(name = "chapter_name", nullable = false, length = 12)
    private String chapterName;

    @Basic(optional = false)
    @Column(name = "chapter_description", nullable = false, length = 12)
    private String chapterDescription;

    @Basic(optional = false)
    @Column(name = "chapter_Vvew_range", nullable = false)
    private int chapterVvewrange;

    @Basic(optional = false)
    @Column(name = "chapter_video_length", nullable = false)
    private int chapterVideoLength;

    @OneToMany(cascade = CascadeType.ALL, mappedBy = "chapterFk", fetch = FetchType.EAGER)
    private Collection<Camera> cameraCollection;

    @OneToMany(cascade = CascadeType.ALL, mappedBy = "operationFk", fetch = FetchType.EAGER)
    private Collection<Camera> cameraCollection1;


在这里,我在章节和相机类中都使用了两种方式绑定。如果您使用复合主键。您必须管理其他嵌入式主键对象。

【讨论】:

之前我的代码不正确。为代码添加 getter 和 setter 并检查它 另外,这是从 Netbeans 生成的代码。如果 ER 没问题,那么答案是 100% 正确的。 非常感谢,您的回答并不完全符合您的要求,但您将我推向了正确的方向。经过一些调整,它就奏效了!

以上是关于Spring OneToMany 与复合键的关系与另一个具有复合键的关系的主要内容,如果未能解决你的问题,请参考以下文章

Prisma 删除与复合键的多对多关系

Laravel 与复合外键的关系

Spring boot JPA - 没有嵌套对象的 JSON 与 OneToMany 关系

如何使用 Spring Data / Hibernate 级联保持 @OneToMany 与 @EmbeddedId 的关系

学说:具有复合键的实体之间的 ManyToX 关系

OneToMany 将 POJO 映射到 JSON Spring