代码之家  ›  专栏  ›  技术社区  ›  broschb

jpa-hibernate复合外键映射

  •  8
  • broschb  · 技术社区  · 14 年前

    我在为某些实体设置jpa映射时遇到问题。我有一个定义如下的父实体。

    @Entity
    @Table(name="EIF_INSTANCE_HDR")
    public class InstanceEntity implements Serializable{
    
        private static final long serialVersionUID = 1L;
    
        @Id
        @GeneratedValue(generator="eif_inst_gen")
        @SequenceGenerator(name="eif_inst_gen",sequenceName="EIF_INSTANCE_SEQ")
        @Column(name = "EAIH_ID")
        private Long eaihid;
    
        @Column(name = "EAD_ID")
        private Long eadid;
    
        @OneToMany(targetEntity=InstanceNotifyEntity.class, mappedBy="instance",fetch=FetchType.EAGER, cascade = CascadeType.ALL)
        private List<InstanceNotifyEntity> userDetails = new ArrayList<InstanceNotifyEntity>();
    
    }
    

    然后,我有一个子实体和一个复合键,还有一个外键指向这个表的主键,如下所示:

    @Entity
    @Table(name="EIF_INST_NOTIFIED")
    public class InstanceNotifyEntity implements Serializable{
    
        private static final long serialVersionUID = 1L;
        
        @Id
        @ManyToOne
        @JoinColumn(name="EAIH_ID", referencedColumnName="EAIH_ID")
        private InstanceEntity instance;
        
        @Id
        @Column(name="USER_ID")
        private Long userId;
    
        @Column(name="COMMENT_TXT")
        private String commentText;
    
    }
    

    我知道子实体是不正确的,但我不确定如何设置这个有一个复合PK。我知道我需要设置一个PK类,但是当一个字段是父类的外键时,我不知道如何设置。一旦设置完成,父实体将如何引用子实体?

    感谢您的帮助。

    2 回复  |  直到 4 年前
        1
  •  13
  •   ScottM    8 年前

    这取决于 JPA 2 spec

    如规范中所述,在这种情况下,有两种方法可以表示子实体的键:

    • @IdClass
    • @EmbeddedId

    EmbeddedId 是的。我选择了 嵌入ID 武断的,但是 IdClass 嵌入ID 意义重大。你可能会做出不同的选择。

    // Child entity's composite primary key
    @Embeddable
    public class InstanceNotifyEntityId implements Serializable {
        Long eaihId;
        Long userId;
    }
    
    // Child entity
    @Entity
    @Table(name="EIF_INST_NOTIFIED")
    public class InstanceNotifyEntity implements Serializable {
        @AttributeOverrides({
          @AttributeOverride(name="userId", column = @Column(name="USER_ID"))
          @AttributeOverride(name="eaihId", column = @Column(name="EAIH_ID"))
        })
        @EmbeddedId
        InstanceNotifyEntityId id;
    
        @MapsId("eaihId")
        @ManyToOne
        InstanceEntity instance;
    
        // ...
     }
    

    userDetails mappedBy

        2
  •  1
  •   buræquete Naveen Kocherla    6 年前

    我也面临同样的问题,并遵循这个答案,但它不是保存子实体与父实体。这是我所做的改动,效果很好。进行以下更改-

    // Child entity's composite primary key class
    
    public class InstanceNotifyEntityId implements Serializable {
    
        @Column(name = "USER_ID")
        Long userId;
    
        @JoinColumn(name = "EAIH_ID")
        @ManyToOne  
        InstanceEntity instance
    }
    
    // Child entity which contain composite primary key as a EmbeddedId, 
    // no need to define any relationship here as we already define 
    // the relationship in composite key class. 
    
    @Entity
    @Table(name = "EIF_INST_NOTIFIED")
    public class InstanceNotifyEntity implements Serializable {
    
        @EmbeddedId
        InstanceNotifyEntityId id;
    }
    
    
    // Parent entity (parent entity mappedby should be your composite 
    // key class instance.child class object which already have the 
    // join column mapping with "EAID_ID")  
    
    @Entity
    @Table(name = "EIF_INSTANCE_HDR")
    public class InstanceEntity implements Serializable {
    
        @OneToMany(mappedBy = "id.instance,fetch=FetchType.EAGER, cascade = CascadeType.ALL)
        private List<InstanceNotifyEntity> userDetails = new ArrayList<InstanceNotifyEntity>();
    }
    

    在保存父实体时,将父对象设置为复合键,如 id.setInstance(parent entire obj)