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