Проблемы подключения трех сущностей в Spring Boot Jpa друг с другом - PullRequest
0 голосов
/ 12 декабря 2018

Предположим, у меня есть таблица 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;

1 Ответ

0 голосов
/ 12 декабря 2018

Зависит от требований вашего бизнеса.Допустим, роль пользователя в проектах будет другой, вы можете ввести другой класс Assignment, тогда он станет 3 @OneToMany :) enter image description here

Вы будете ссылаться на User, Project, Role в Assignment с @ManyToOne, но вы можете или не можете использовать @OneToMany.Есть очень хорошая статья о лучших методах реализации @OneToMany: https://vladmihalcea.com/the-best-way-to-map-a-onetomany-association-with-jpa-and-hibernate благодаря @ vlad-mihalcea

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...