假设我的数据库中有一个表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
通过将FK中的PK组合到名称表来连接User
,Project
和Role
。现在,据我所知,通常在Spring Boot JPA中使用@Embeddable
注释的新类中提供了组合PK。从这个角度来看,我将执行以下操作:
@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:在类路径资源[org / springframework / boot / autoconfigure / orm / jpa / HibernateJpaConfiguration.class]中创建名称为'entityManagerFactory'的bean时出错:调用init方法失败;嵌套的异常是javax.persistence.PersistenceException:[PersistenceUnit:默认]无法构建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;
答案 0 :(得分:3)
取决于您的业务需求。
假设用户的角色在项目中会有所不同,您可以引入另一个类Assignment
,然后将其变为3 @OneToMany
:)
您将使用User
来引用Project
中的Role
,Assignment
,@ManyToOne
,但是您可能需要也可能不需要使用{{1} }。关于实现@OneToMany
的最佳实践的非常好的文章:https://vladmihalcea.com/the-best-way-to-map-a-onetomany-association-with-jpa-and-hibernate感谢@ vlad-mihalcea