包含外键的复合主键

composite primary key which contains a foreign key

我有一个名为 UserWithRoles 的实体:

@Entity
@Getter
@Setter
public class UserWithRoles implements Serializable
{
  @Id
  @GeneratedValue( strategy = GenerationType.AUTO )
  private int id;

  private String name;

  private String password;

  @OneToMany( mappedBy = "user" )
  private List<UserRole> roles;
}

用户角色实体:

@Entity
@Getter
@Setter
@IdClass( UserRolePK.class )
@Inheritance( strategy = InheritanceType.JOINED )
@DiscriminatorColumn( name = "roleType", discriminatorType = DiscriminatorType.STRING, length = 10 )
abstract public class UserRole implements Serializable
{
  @Id
  // It should be mapped as a foreign PK by user.id (user field declared below)
  private int userID;

  @Id
  private String roleType;

  @ManyToOne
  @JoinColumn( name="user_id", referencedColumnName = "id" )
  private UserWithRoles user;  
}

主键class UserRolePK:

@Data
public class UserRolePK implements Serializable
{
  private int userID;
  private String roleType;  
}

我想为 UserRole 创建复合 PK:UserWithRoles.id + UserRole.roleType 我怎样才能将它映射到数据库?我应该在 PK class 中使用 UserWithRoles 类型而不是 ID 吗?这是个好主意吗?或者我应该对 UserRole 使用普通的 PK?这种关系类似于 ClientOrder 和 ClientOrdetItem 实体之间的关系:(ClientOrder.id + ClientOrderItem.num)

您正在使用派生身份。

您需要将 UserRole 更改为如下所示:

@Entity
@Getter
@Setter
@IdClass( UserRolePK.class )
@Inheritance( strategy = InheritanceType.JOINED )
@DiscriminatorColumn( name = "roleType", discriminatorType = DiscriminatorType.STRING, length = 10 )
abstract public class UserRole implements Serializable
{    
  @Id
  private String roleType;

  @Id
  @ManyToOne
  @JoinColumn( name="user_id", referencedColumnName = "id" )
  private UserWithRoles user;  
}

即去掉userID字段,在user字段中添加@Id注解

并将 UserRolePK 更改为如下所示:

@Data
public class UserRolePK implements Serializable
{
  private int user;
  private String roleType;  
}

即把userID字段的名称改成user,以匹配UserRole中的@Id字段的名称(但其类型必须仍然匹配 UserWithRoles PK 字段的类型,id).

派生标识在 JPA 2.1 规范的第 2.4.1 节中进行了讨论。