Предположим, у меня есть таблица project
в моей базе данных.У каждого project
есть много users
, а у каждого user
может быть много projects
.Это будет классическая ManyToMany
-корреляция, и поэтому, если бы я хотел изобразить это в моем Spring Boot JPA, я мог бы сделать следующее:
Настройте мои сущности и подключите их:
@Entity
public class User {
@id
@Column(name="ID")
public int id;
@ManyToMany
public Set<Project> projectSet;
}
@Entity
@Table(name="PROJECT")
public class Project {
@id
@Column("ID")
private int id;
@ManyToMany
private Set<User> users;
}
Реализация моего репозитория:
@Repository
public interface ProjectRepo implements JpaRepository<Project, Integer> {
public Set<User> getAllUsers();
}
Теперь давайте предположим, что я хотел бы указать, какую роль каждый пользователь играл в этом проекте.Таким образом, у меня будет таблица role
, в которой указаны различные роли со следующим представлением сущности:
@Entity
@Table(name="ROLES")
public class Role {
@id
@Column(name="ID")
private int id;
@Column(name="DESCRIPTION")
private String description;
}
Но как это связано с моими пользователями и проектами?Итак, я хочу показать, что у одного пользователя может быть одна роль в одном проекте, но много ролей во многих проектах.Кроме того, одна роль может быть назначена многим пользователям в одном или нескольких проектах, а в одном проекте может быть много пользователей, у каждого из которых есть только одна роль, но есть много ролей.Если я просто добавлю @ManyToMany Set<Roles> roleSet
к своему Users
, я не смогу сказать, какой пользователь будет иметь какую роль в каком проекте.Так как это изобразить?Нужно ли создавать третий класс для их соединения?
Редактировать 1:
Чтобы пояснить, я попытаюсь предоставить код для предложенияв ответе marknote -
Давайте предположим, что у меня есть классы сверху (Project
, User
, Role
), и я хочу изобразить, что каждый пользователь имеет определенную роль в одном проекте, но может иметьдругая роль в другом проекте.Кроме того, несколько ролей в одном проекте невозможны (для простоты).
Поэтому я бы создал новый класс Assignment
(почти так же, как я бы решил этот вариант использования в моей структуре базы данных) исоедините его с моим User
, моим Project
и моим Role
.
@Entity
@Table(name="USER")
public class User {
@id
@Column(name="id")
private int id;
@Column(name="firstname")
private String firstname;
@Column(name="lastname")
private String lastname;
@OneToMany
private List<Assignment> assignments;
//getters and setters and stuff
}
@Entity
@Table(name="PROJECT")
public class Project {
@id
@Column(name="PNUM")
private String pnum;
@Column(name="PNAME")
private String pname;
@OneToMany
private List<Assignment> assignments;
//getters and setters and stuff
}
@Entity
@Table(name="ROLE")
public class Role {
@id
@Column(name="id")
private int id;
@Column(name="DESCRIPTION")
private String description;
@OneToMany
private List<Assignment> assignments;
//getters and setters and stuff
}
Пока все в порядке, поэтому я собираюсь создать следующий класс Assignment
.Мне нужно иметь возможность отслеживать от User
до Project
и Role
, поэтому мне нужны три поля.Давайте представим (обычный) вариант использования: таблица Assignment
соединяет User
, Project
и Role
, объединяя PK из FK с таблицами имен.Теперь объединенный PK в Spring Boot JPA обычно (насколько я знаю) предоставляется в новом классе, который использует аннотацию @Embeddable
.С этой точки зрения я бы сделал следующее:
@Embeddable
public class AssignmentId implements Serializable {
private User user;
private Project project;
private Role role;
}
И изменил бы мой Assignment
-класс на:
@Entity
@Table(name="ASSIGNMENT")
public class Assignment {
@EmbeddedId
private AssignmentId assignmentId;
}
Теперь, когда я делаю это таким образом, я сталкиваюсь сошибка при попытке запуска spring-boot:
org.springframework.beans.factory.BeanCreationException: ошибка создания бина с именем 'entityManagerFactory', определенным в ресурсе пути к классу [org / springframework / boot / autoconfigure /orm / jpa / HibernateJpaConfiguration.class]: сбой вызова метода init;вложенное исключение - javax.persistence.PersistenceException: [PersistenceUnit: default] Невозможно построить Hibernate SessionFactory;Вложенное исключение: org.hibernate.MappingException: Не удалось определить тип для: com.demo.example.entity.Project, в таблице: назначение, для столбцов: [org.hibernate.mapping.Column (project)]
Может кто-то относится к этой ошибке?Это может быть проблема с @EmbeddedId
Я думаю.
Редактировать 2
Проблема с классом @Embedded
.При подключении Entity
к элементу возникают проблемы:
private Role role;
private Project project;
private User user;