【问题标题】:JPA primary key on 2 referenced fields2个引用字段上的JPA主键
【发布时间】:2012-10-14 16:02:59
【问题描述】:

好的,我已经尝试了所有方法,但无法使其正常工作:

我有下表:

  • user_id int ,引用 users.id
  • platform_id int ,引用platforms.id
  • 字段1
  • 字段2
  • ...

我的主键(在数据库中和逻辑上)是user_idplatform_id 的组合。

我想创建一个复合键,它将 User 和 Platform 类作为成员(就像我对常规 OneToOne 或 OneToMany 关系所做的那样)。

我希望复合键具有实际的类引用,而不仅仅是 id(稍后当我需要实际引用进行某些计算时对我来说更容易)。

此外,我需要 User 类与此 UserPlatformData 类建立 OneToMany 关系。

我能够使用 User 和 Platform 创建一个 Embeddable 类,但即使 pk 相同(导致 duplicate entry for key primary...),JPA 总是会插入并且永远不会更新现有记录。

如何创建一个主键包含两个其他引用(不是原语)的类?

【问题讨论】:

    标签: hibernate jpa


    【解决方案1】:
    1. 使用@IdClass 注释和两个@Id 注释声明您的实体。 id 字段类型有两种选择:
      (i) 基本类型:匹配数据库列 OR
      (ii) 非基本类型:通过 FK 引用为 @ManyToOne 的实体对象,允许 FK 关系成为 PK 的一部分。 你说过你想要第二种情况:

        @Entity   
        @IdClass(UserPlatformId.class)       
        public class UserPlatform {  
      
             @Id 
             @ManyToOne
             User user;
             @Id
             @ManyToOne
             Platform platform;
      
          // ...
      
       }
      
    2. 声明一个 javabean id 类来描述复合 PK 字段。

      • 这里的字段类型必须是基本类型,匹配底层DB列,基本类型与User类的@Id字段和Platform类的@Id字段相同。这里始终使用基本类型,即使您对实体 @Id 字段(上面的 ii)使用了非基本类型。
      • Id 类中的字段名称必须与实体中的字段名称匹配。 因此,@IdClass 充当了从实体中的非基本类型到数据库中的基本类型的映射形式:
    public class UserPlatformId {
    
          int user;   
          int platform;
    
          public UserPlatformId();
          public UserPlatformId(int userId, int platformId) { 
                this.user=userId; this.platform=platformId; }
    
          public int getUser() { // ...};
          public int getPlatform() { // ...};
    }
    

    您可以省略 setter 方法,而是使用一个额外的构造函数来预先设置字段。一旦创建,Id 应该是不可变的。

    开始 =:-)

    【讨论】:

      猜你喜欢
      • 2013-01-21
      • 1970-01-01
      • 2020-04-21
      • 1970-01-01
      • 1970-01-01
      • 2016-06-04
      • 2015-06-22
      • 1970-01-01
      • 2021-12-13
      相关资源
      最近更新 更多