如何在 spring boot jpa 中映射实体? [英] How can i mapping entities in spring boot jpa?

查看:51
本文介绍了如何在 spring boot jpa 中映射实体?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我是 Spring Boot JPA 的新手

我对 JPA 实体映射有疑问.

我的 MySql 数据库中有 4 个表

空间、项目、问题、成员

SPACE 是一个包含多个 PROJECT 的大项目.

PROJECT 包含多个问题.

和 MEMBER 只能加入 1 个 SPACE 和多个 PROJECT,其中 MEMBER 属于 SPACE.成员可以写多个ISSUE

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

这里有所有实体:

会员

@Entity@Table(name = "成员")公共类成员{//members 是项目实体中的属性名称.@ManyToMany(mappedBy = "members")设置<项目>项目;@Id@GeneratedValue(strategy = GenerationType.IDENTITY, generator = "native")@Column(name = "MEMBER_ID")私人长ID;@ManyToOne@JoinColumn(name = "SPACE_ID")私人空间;公共长 getId() {返回标识;}公共无效setId(长ID){this.id = id;}公共空间 getSpace() {返回空间;}公共无效集空间(空间空间){this.space = 空间;}公共集<项目>获取项目(){回归项目;}public void setProjects(Set<Project>项目){this.projects = 项目;}}

空格

@Entity@Table(name = "空格")公共类空间{@Id@GeneratedValue(strategy = GenerationType.IDENTITY, generator = "native")@Column(name = "SPACE_ID")私人长ID;公共长 getId() {返回标识;}公共无效setId(长ID){this.id = id;}}

问题

@Entity@Table(name = "问题")公开课问题{@Id@GeneratedValue(strategy = GenerationType.IDENTITY, generator = "native")@Column(name = "ISSUE_ID")私人长ID;@ManyToOne@JoinColumn(name = "MEMBER_ID")私人会员;@ManyToOne@JoinColumn(name = "PROJECt_ID")私人项目项目;公共长 getId() {返回标识;}公共无效setId(长ID){this.id = id;}公共成员 getMember() {回归会员;}public void setMember(Member member) {this.member = 会员;}公共项目 getProject() {回归项目;}public void setProject(项目项目){this.project = 项目;}}

项目

@Entity@Table(name = "项目")公共类项目{@ManyToMany@加入表(name = "PROJECTS_MEMBERS",joinColumns = @JoinColumn(name = "PROJECT_ID"),inverseJoinColumns = @JoinColumn(name = "MEMBER_ID"))//是指其他Entity的id,本例中为members设置<成员>会员;@Id@GeneratedValue(strategy = GenerationType.IDENTITY, generator = "native")@Column(name = "PROJECT_ID")私人长ID;@ManyToOne@JoinColumn(name = "SPACE_ID")私人空间;公共集<成员>获取成员(){回归会员;}public void setMembers(Set members) {this.members = 成员;}公共长 getId() {返回标识;}公共无效setId(长ID){this.id = id;}公共空间 getSpace() {返回空间;}公共无效集空间(空间空间){this.space = 空间;}}

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

注意不要随意使用 FetchType.EAGER 这就是为什么 =>Java Persistence API 中 FetchType LAZY 和 EAGER 的区别?

I'm new in Spring Boot JPA

I have questions in JPA Entity mappings.

there is 4 tables in my MySql DB

SPACE, PROJECT, ISSUE, MEMBER

SPACE is Big Project which contains multiple PROJECT.

PROJECT contains multiple ISSUE.

and MEMBER can join only 1 SPACE and multiple PROJECT which MEMBER belongs to SPACE. MEMBER can write multiple ISSUE

in this situation, my ERD model is correct?

my ERD

and please check my jpa mappings. If there's anything wrong, please point it out.

    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;

I've been thinking about it for days, but I can't solve it because I lack knowledge. Please help me.

解决方案

Assuming I got your situation right, you have A member that can have one Space and multiple project, space has multiple projects, every project can have more than one issue, every member can write more then one issue for each project.

Due to the suggestion the ERD you posted it's not corrected.

Here is the correct ERD

(I just wrote the Foreign Keys and Primary Keys, the rest its up to you)

And here you have all the entites:

Member

@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;
    }
}

Space

@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;
    }
}

Issue

@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;
    }
}

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;
    }


}

You don't have to put necessarily both @ManyToOne and @OneToMany annotation, the back-reference could be useful in some use case, you have to see if you need it or not. Remember the back reference could cause problems with deserialization, creating a stack overflow by circular reference. You can avoid this, using transient keyword or various annotation (depending on the library you are using, Jackson, Gson, ecc..).

Be careful to don't use FetchType.EAGER randomly here's the why => Difference between FetchType LAZY and EAGER in Java Persistence API?

这篇关于如何在 spring boot jpa 中映射实体?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆