Проблемы с аннотацией @ManyToMany Hibernate - внешний ключ имеет неправильный номер столбца (должно быть 3) - PullRequest
0 голосов
/ 13 декабря 2018

Я хочу добавить следующую структуру базы данных в мой 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)
);

Итак, я начал с создания трех сущностей User, Project и Role (см. Конец этого постадля полных занятий).Затем я создал класс Assignment для соединения, включающий @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 предусмотрено три (один join и два столбца inverseJoin).Что я сделал не так?

Классы:

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

}

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


}

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

}
...