【问题标题】:How can i mapping entities in spring boot jpa?我如何在 Spring Boot jpa 中映射实体?
【发布时间】:2021-10-16 10:00:44
【问题描述】:

我是 Spring Boot JPA 的新手

我对 JPA 实体映射有疑问。

我的 MySql DB 中有 4 个表

空间、项目、问题、成员

SPACE 是包含多个 PROJECT 的大项目。

PROJECT 包含多个 ISSUE。

MEMBER 只能加入 1 个 SPACE 和 MEMBER 属于 SPACE 的多个 PROJECT。 MEMBER可以写多个ISSUE

在这种情况下,我的 ERD 模型是否正确?

my ERD

请检查我的 jpa 映射。 如有不妥,请指出。

    SPACE

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "space_no")
    private Long spaceNo;

    @NotEmpty
    @Column(name = "space_name", unique=true, length = 100)
    private String spaceName;

    /** 1:N relation */
    @OneToMany(mappedBy = "smsSpace")
    private List<PmsProject> pmsProjects = new ArrayList<>();

    PROJECT
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "project_no")
    private Long projectNo;

    @Column(name ="space_no")
    private Long spaceNo;

    @Column(name = "project_name", length = 100)
    private String projectName;

    /** 1:N relation */
    @OneToMany(mappedBy = "pmsProject")
    private List<ImsIssue> imsIssues = new ArrayList<>();

    @OneToMany(mappedBy = "pmsProject")
    private List<PmsProjectMember> projectMembers = new ArrayList<>();

    /** N:1 relation */
    @ManyToOne
    @JoinColumn(name = "space_no", referencedColumnName = "space_no", insertable = false, updatable = false)
    private SmsSpace smsSpace;
MEMBER

  @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "member_no")
    private Long memberNo;

    @Column(name = "mail_address", unique=true, length = 100)
    private String mailAddress;

    @Column(name = "name", length = 100)
    private String name;

    @Column(name = "keyword", length = 1000)
    private String keyword;

    @Column(name = "image", length = 1000)
    private String image;

    @Column(name = "password", length = 1000)
    private String password;

    @Column(name = "user_id", length = 50)
    private String userId;

    @Enumerated(EnumType.STRING)
    private MemberRole role;

    public void encodingPassword(String password) {
        this.password = password;
    }

    /** 1:N realtion */
    @OneToMany(mappedBy = "mmsMember")
    private List<PmsProjectMember> projectMembers = new ArrayList<>();
ISSUE
 @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "issue_no")
    private Long issueNo;

    @Column(name ="project_no")
    private Long projectNo;

    @Column(name = "issue_name", length = 1000)
    private String issueName;

    @Column(name = "priority")
    private Long priority;

    @Column(name = "status", length = 20)
    private String status;

    @Column(name = "summary", length = 100)
    private String summary;

    @Column(name = "is_overdue")
    private Long isOverdue;

    @Column(name = "issue_type_cd")
    private String issueTypeCd;

    /** N:1 relation */
    @ManyToOne
    @JoinColumn(name = "project_no", referencedColumnName = "project_no", insertable = false, updatable = false)
    private PmsProject pmsProject;
PROJECTMEMBER

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "group_no")
private Long groupNo;

@ManyToOne(fetch = FetchType.EAGER)
@JoinColumn(name = "member_no")
private MmsMember mmsMember;

@ManyToOne(fetch = FetchType.EAGER)
@JoinColumn(name = "project_no")
private PmsProject pmsProject;

我已经想了好几天了,但由于我缺乏知识,我无法解决它。请帮帮我。

【问题讨论】:

  • 在回答之前我先问你一件事,你是一般数据库新手吗?
  • @A.Caldarigi 我几乎是新人。为什么?
  • 关于 ERD:为什么您的 project 表中有 Member_no?有什么用?在你的 issue 表中有一个 Member_no,那个应该是一个 Fk。(你只希望一个用户出现在那个问题中?)你不应该注意哪个用途是在哪个空间中?
  • @A.Caldarigi 非常感谢您的回答。我按照你说的修改了。我添加了 PROJECTMEMBER JPA 映射。项目 M:N 成员。 JPA实体映射有问题吗?
  • 在JPA实体中存在各种错误:首先都是多对多关系,不需要任何额外的实体,您使用@ManyToMany注释在每个实体上映射一个额外的字段,更多信息可以在这里找到@ 987654322@

标签: mysql spring spring-boot jpa


【解决方案1】:

假设我的情况是正确的,你有一个成员可以有一个空间和多个项目,空间有多个项目,每个项目可以有多个问题,每个成员可以为每个项目编写多个问题。

由于建议,您发布的 ERD 未更正。

这是正确的 ERD

(我只是写了外键和主键,其余的由你决定)

这里有所有的实体:

会员

@Entity
@Table(name = "MEMBERS")
public class Member {

    //members is the property name in Project entity.
    @ManyToMany(mappedBy = "members")
    Set<Project> projects;
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY, generator = "native")
    @Column(name = "MEMBER_ID")
    private Long id;
    @ManyToOne
    @JoinColumn(name = "SPACE_ID")
    private Space space;

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public Space getSpace() {
        return space;
    }

    public void setSpace(Space space) {
        this.space = space;
    }

    public Set<Project> getProjects() {
        return projects;
    }

    public void setProjects(Set<Project> projects) {
        this.projects = projects;
    }
}

空格

@Entity
@Table(name = "SPACES")
public class Space {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY, generator = "native")
    @Column(name = "SPACE_ID")
    private Long id;

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }
}

问题

@Entity
@Table(name = "ISSUES")
public class Issue {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY, generator = "native")
    @Column(name = "ISSUE_ID")
    private Long id;

    @ManyToOne
    @JoinColumn(name = "MEMBER_ID")
    private Member member;


    @ManyToOne
    @JoinColumn(name = "PROJECt_ID")
    private Project project;

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public Member getMember() {
        return member;
    }

    public void setMember(Member member) {
        this.member = member;
    }

    public Project getProject() {
        return project;
    }

    public void setProject(Project project) {
        this.project = project;
    }
}

项目

@Entity
@Table(name = "PROJECTS")
public class Project {
    @ManyToMany
    @JoinTable(
            name = "PROJECTS_MEMBERS",
            joinColumns = @JoinColumn(name = "PROJECT_ID"),
            inverseJoinColumns = @JoinColumn(name = "MEMBER_ID"))//Is referring to the id of the other Entity, in this case, members
    Set<Member> members;
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY, generator = "native")
    @Column(name = "PROJECT_ID")
    private Long id;
    @ManyToOne
    @JoinColumn(name = "SPACE_ID")
    private Space space;

    public Set<Member> getMembers() {
        return members;
    }

    public void setMembers(Set<Member> members) {
        this.members = members;
    }

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public Space getSpace() {
        return space;
    }

    public void setSpace(Space space) {
        this.space = space;
    }


}

您不必同时添加 @ManyToOne 和 @OneToMany 注释,反向引用在某些用例中可能很有用,您必须看看是否需要它。请记住,反向引用可能会导致反序列化问题,通过循环引用创建堆栈溢出。您可以使用瞬态 keyword 或各种注释(取决于您使用的库,Jackson、Gson、ecc..)来避免这种情况。

注意不要随意使用 FetchType.EAGER 这就是为什么 => Difference between FetchType LAZY and EAGER in Java Persistence API?

【讨论】:

  • 非常感谢您的详细回复。我会研究和分析你发布的答案。如果您有任何问题,我会在 cmets 中问您。非常感谢!
  • 如果我只知道会员的邮箱信息,如何获取会员所属的空间和项目?是不是应该用email从memberRepository中获取MmsMember的方法,找出MmsMember的spaceNo,然后查找有spaceNo的项目?我目前在项目和成员中遇到无限恢复错误。
  • 您可以这样做,也可以将本机查询与 Join 结合使用。个人建议,尝试仅使用查询来实现此结果,然后尝试使用存储库
  • 顺便说一下,理论上您可以在存储库中执行一个 customMethod 类似findByEmail(String email) 的操作,然后从给定对象中获取项目和空间参数
  • 哦,我是个傻瓜。如果我只使用 findByEmail 方法,则 smsSpace 和 pmsProject 包含在里面。但是只有一个项目有什么问题呢? ProjectMember 表存储三个项目。 link link 这些是调试和数据库捕获
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-09-15
  • 2020-05-07
  • 2011-07-13
  • 1970-01-01
  • 1970-01-01
  • 2020-07-04
相关资源
最近更新 更多