java - Spring Boot Jpa 中的三个实体相互连接时出现问题

标签 java spring spring-data-jpa

假设我有一张 table 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();
}

现在假设我想指定每个用户在此项目中的角色。所以我会有一张 table 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的答案中提供建议的代码 -

假设我有上面的类( ProjectUserRole ),并且我想描述每个用户在一个项目中具有特定角色,但可能在另一个项目中具有另一个角色。此外,一个项目中不可能有多个角色(为了简单起见)。

所以我会创建一个新类 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 -类(class)。我需要能够从 User 进行追踪至Project并发送至Role ,所以我需要这三个字段。让我们想象一下(通常的)用例:表 Assignment正在连接 User , ProjectRole通过将 FK 中的组合 PK 与名称表结合起来。现在,Spring Boot JPA 中的组合 PK 通常(据我所知)在使用 @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: Error creating bean with name 'entityManagerFactory' defined in class path resource [org/springframework/boot/autoconfigure/orm/jpa/HibernateJpaConfiguration.class]: Invocation of init method failed; nested exception is javax.persistence.PersistenceException: [PersistenceUnit: default] Unable to build Hibernate SessionFactory; nested exception is org.hibernate.MappingException: Could not determine type for: com.demo.example.entity.Project, at table: assignment, for columns: [org.hibernate.mapping.Column(project)]

有人可以解决这个错误吗?这可能是 @EmbeddedId 的问题我想。

编辑2

问题出在 @Embedded类(class)。 Entity 接线有问题到一个元素:

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

最佳答案

取决于您的业务需求。 假设用户在项目中的角色会有所不同,您可以引入另一个类 Assignment ,则变为 3 @OneToMany :) enter image description here

您将引用User , Project , RoleAssignment@ManyToOne ,但您可能需要也可能不需要使用 @OneToMany 。有一篇关于实现最佳实践的非常好的文章@OneToMany :https://vladmihalcea.com/the-best-way-to-map-a-onetomany-association-with-jpa-and-hibernate感谢@vlad-mihalcea

关于java - Spring Boot Jpa 中的三个实体相互连接时出现问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53733602/

相关文章:

java - 将带有 @ManyToOne 的子实体删除到其他实体时出现 NullPointerException

java - 在 Java 中通过 SOCKS 代理进行 SOAP 调用

Java变量对象搜索列表

java - 执行和sql字符串

java - 如何将 Swing DISPOSE_ON_CLOSE 连接到菜单栏选项

java - Spring Boot 使用 Spring Profile 忽略来自 Java 配置类的 bean

java - 转换 PEM 证书以在 JAVA Spring Framework 中使用

Spring Cloud的@RefreshScope导致 Controller 映射与其自身冲突

java - 通过 JPA 中的@OneToMany 使 2 个不同的父实体引用子实体

java - 如何在 Spring Data JPA 中干净地捕获 DAO 服务层异常