覆盖@CollectionTable对主键列的引用

时间:2016-05-13 11:57:19

标签: java hibernate jpa

简而言之

JPA文档说CollectionTable.joinColumns属性是“集合表的外键列,它引用了实体的主表。”

我可以使它不是实体表的主键列,而是另一个具有唯一值的列吗?

详细

有一个遗留数据库,其中包含以下表格(简化):

staff:
  user_id (int)
  user_name (varchar, primary key)

staff_privileges:
  id_user (int)
  privileges_id (int) 
  privileges_status (boolean)

现在我将Hibernate引入项目并尝试将这些表映射到实体:

@Entity
@Table(name = "staff")
public class User {

  @Column(name = "user_id")
  private Integer userId;

  @Id
  @Column(name = "user_name")
  private String userName;    // primary key column (legacy, cannot be changed)

  @ElementCollection
  @CollectionTable(name = "staff_privileges", joinColumns = @JoinColumn(name = "id_user"))
  @MapKeyColumn(name = "privileges_id")
  @Column(name = "privileges_status")
  private Map<Integer, Boolean> privileges; // privilegeId <-> isEnabled
}

无效,因为@CollectionTable会创建对主键的引用:staff_privileges.id_user -> staff.user_name (primary key)。 它应该是:staff_privileges.id_user -> staff.id_user。 有没有办法覆盖这个参考?是否有任何Hibernate或JPA注释?我想保持简单,如果可能的话,不要引入任何新的实体或嵌入。

2 个答案:

答案 0 :(得分:3)

假设每个用户user_id也是唯一的,那么您只需将@Id注释User移至userId:您的JPA提供商不知道实际的PK在数据库中,只要该值是唯一的,就不会引起任何问题。

略有不同的背景但请参阅:

https://en.wikibooks.org/wiki/Java_Persistence/Identity_and_Sequencing#No_Primary_Key

  

JPA Id并不总是必须匹配数据库表primary   键约束,也不是主键或唯一约束。

唯一的区别是,如果您从映射中对表进行逆向工程,那么将在user_id而不是user_name上使用PK创建staff表。

答案 1 :(得分:0)

您可以使用refrencedColumnNameid_user而不是user_name映射为加入列。

Hibernate documentation对此参数有更简洁的描述:

  

使用@JoinColumn注释声明连接列   看起来像@Column注释。它还有一个名为的参数   的 referencedColumnName 即可。 此参数声明了列中的列   将用于加入的目标实体。请注意,使用时    referencedColumnName 到非主键列,关联类   必须是可序列化的。另请注意,referencedColumnName为a   非主键列必须映射到具有单个的属性   列(其他情况可能不起作用)。

@Entity
@Table(name = "staff")
public class User {

  ...

  @ElementCollection
  @CollectionTable(name = "staff_privileges", joinColumns = @JoinColumn(name = "id_user", referencedColumnName = "user_id"))
  @MapKeyColumn(name = "privileges_id")
  @Column(name = "privileges_status")
  private Map<Integer, Boolean> privileges;
}

有关详情,请查看此问题:What is referencedColumnName used for in JPA?