包含外键的复合主键

时间:2016-02-16 23:58:35

标签: jpa orm composite-primary-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;
}

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
  // 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;  
}

主键类UserRolePK:

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

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

1 个答案:

答案 0 :(得分:2)

您正在使用派生身份。

您需要将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字段并在@Id字段中添加user注释。

UserRolePK更改为:

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

也就是说,将userID字段的名称更改为user,以匹配@IdUserRole字段的名称(但其类型仍必须与UserWithRoles PK字段的类型,id)。

JPA 2.1规范第2.4.1节讨论了派生身份。