首页 > 解决方案 > @ManyToMany Annotation Hibernate 的问题 - 外键的列数错误(应该是 3)

问题描述

我想将以下数据库结构添加到我的 Jpa 中:

CREATE TABLE USER (
    id int PRIMARY KEY AUTO_INCREMENT,
    firstname varchar(255),
    lastname varchar(255)
);
CREATE TABLE PROJECT (
    PNUM varchar(255) PRIMARY KEY,
    PNAME varchar(255) NOT NULL
);
CREATE TABLE ROLE (
    id int PRIMARY KEY AUTO_INCREMENT,
    description varchar(255) NOT NULL
);
CREATE TABLE ASSIGNMENT (
    user_id int,
    project_num varchar(255),
    role_id int,
    foreign key (user_id) REFERENCES USER(ID),
    FOREIGN KEY (project_num) REFERENCES PROJECT(PNUM),
    FOREIGN KEY (role_id) REFERENCES ROLE(id),
    PRIMARY KEY (user_id, project_num, role_id)
);

所以我开始制作三个 Entity UserProject并且Role(完整课程请参见本文末尾)。然后我Assignment为连接创建了-class,包括@EmbeddedId

分配类:

package com.demo.example.entity;

import javax.persistence.EmbeddedId;
import javax.persistence.Entity;

@Entity
public class Assignment {


    @EmbeddedId
    private AssignmentId id;

    public Assignment() {
        // TODO Auto-generated constructor stub
    }

    public AssignmentId getId() {
        return this.id;
    }

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

}

AssignmentId 类

package com.demo.example.entity;

import java.io.Serializable;

import javax.persistence.Embeddable;

@Embeddable
public class AssignmentId implements Serializable {

    private Role role;
    private Project project;
    private User user;

    public AssignmentId(Project project, Role role, User user) {
        this.project = project;
        this.role = role;
        this.user = user;
    }

    public Project getProject() {
        return project;
    }

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

    public Role getRole() {
        return role;
    }

    public void setRole(Role role) {
        this.role = role;
    }

    public User getUser() {
        return user;
    }

    public void setUser(User user) {
        this.user = user;
    }


}

最后,我声明了作业的存储库:

package com.demo.example.repository;

import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;

import com.demo.example.entity.Assignment;
import com.demo.example.entity.AssignmentId;

@Repository
public interface AssignmentRepository extends JpaRepository<Assignment, AssignmentId> {

}

现在在运行 JUnit-Test 时,我遇到了以下错误:

Caused by: org.hibernate.AnnotationException: A Foreign key refering com.demo.example.entity.Assignment from com.demo.example.entity.User has the wrong number of column. should be 3

我已经看到了很多关于该怎么做的建议,但没有一个有效(而且,大多数时候“应该”的值是 2。这甚至可以用 3 解决吗?)。但我无法弄清楚为什么我的User-Entity 列数错误?它在@JoinTable-Annotation 中提供了三个(一个join和两个inverseJoin-Columns)。我做错了什么?

课程:

用户.java:

package com.demo.example.entity;

import java.util.HashSet;
import java.util.Set;

import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;
import javax.persistence.Table;

@Entity
@Table(name="USER")
public class User {

    @Id @GeneratedValue(strategy=GenerationType.IDENTITY)
    @Column(name="user_id")
    private int user_id;

    @Column(name="firstname")
    private String firstname;

    @Column(name="lastname")
    private String lastname;

    @ManyToMany(cascade= {CascadeType.ALL})
    @JoinTable(
            name="ASSIGNMENT",
            joinColumns = {@JoinColumn(name="user_id")},
            inverseJoinColumns = { @JoinColumn(name="pnum"),
                    @JoinColumn(name="role_id")}
    )
    private Set<Assignment> assignments = new HashSet<Assignment>();

    public Set<Assignment> getAssignments() {
        return this.assignments;
    }

    public User() {
    }

    public User(String firstname, String lastname) {
        this.firstname = firstname;
        this.lastname = lastname;
    }

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

    public void setFirstname(String firstname) {
        this.firstname = firstname;
    }

    public void setLastname(String lastname) {
        this.lastname = lastname;
    }

    public int getId() {
        return user_id;
    }

    public String getFirstname() {
        return firstname;
    }

    public String getLastname() {
        return lastname;
    }

}

项目.java:

package com.demo.example.entity;

import java.util.HashSet;
import java.util.Set;

import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;
import javax.persistence.Table;

@Entity
@Table(name="PROJECT")
public class Project {

    @Id 
    @Column(name="PNUM")
    private String pnum;

    @Column(name = "PNAME", nullable = false)
    private String pname;

    @ManyToMany(cascade= {CascadeType.ALL})
    @JoinTable(
            name="ASSIGNMENT",
            joinColumns = {@JoinColumn(name="pnum")},
            inverseJoinColumns = { @JoinColumn(name="user_id"),
                    @JoinColumn(name="role_id")}
    )
    private Set<Assignment> assignments = new HashSet<Assignment>();

    public Set<Assignment> getAssignments() {
        return this.assignments;
    }

    public Project() {
        // TODO Auto-generated constructor stub
    }

    public Project(String PNUM, String PNAME) {
        this.pnum = PNUM;
        this.pname = PNAME;
    }

    public String getPnum() {
        return pnum;
    }

    public void setPnum(String pnum) {
        this.pnum = pnum;
    }

    public String getPname() {
        return pname;
    }

    public void setPname(String pname) {
        this.pname = pname;
    }


}

角色.java:

package com.demo.example.entity;

import java.util.HashSet;
import java.util.Set;

import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;
import javax.persistence.Table;

@Entity
@Table(name="ROLE")
public class Role {

    @Id @GeneratedValue(strategy=GenerationType.IDENTITY)
    @Column(name="role_id")
    private int role_id;

    @Column(name = "NAME", nullable = false)
    private String name;

    @ManyToMany(cascade= {CascadeType.ALL})
    @JoinTable(
            name="ASSIGNMENT",
            joinColumns = {@JoinColumn(name="role_id")},
            inverseJoinColumns = { @JoinColumn(name="user_id"),
                    @JoinColumn(name="project_id")}
    )
    private Set<Assignment> assignments = new HashSet<Assignment>();

    public Set<Assignment> getAssignments() {
        return this.assignments;
    }

    public Role(String name) {
        this.name = name;
    }

    public int getId() {
        return this.role_id;
    }

    public String getName() {
        return this.name;
    }

    public void setName(String name) {
        this.name = name;
    }

}

标签: javahibernatespring-data-jpamany-to-many

解决方案


推荐阅读