java jpa hibernate 复合外键映射

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/3323751/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-30 01:18:54  来源:igfitidea点击:

jpa hibernate composite foreign key mapping

javahibernatejpa

提问by broschb

I am having trouble setting up jpa mappings for some entities. I have a parent entity defined like the following.

我在为某些实体设置 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>();
}

I then have a child entity w/ a composite key, and a foreign key to the primary key of this table as follows:

然后我有一个带有复合键的子实体,以及该表主键的外键,如下所示:

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

I know the child entity is incorrect, but I am unsure how to set this up to have a composite PK. I know I need to setup a PK class, but I am not sure how to do that when one field is a foreign key to the parent class. And once that is setup how would the parent reference the child entity?

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

Any help is appreciated.

任何帮助表示赞赏。

回答by Dan LaRocque

This is governed by JPA 2 specsection 2.4.1, "Primary Keys Corresponding to Derived Identities". The section contains two examples directly applicable to your problem.

这由JPA 2 规范第 2.4.1 节“与派生身份对应的主键”管理。本节包含两个直接适用于您的问题的示例。

As described in the spec, there are two ways to represent the child entity's key in this case:

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

  • @IdClass
  • @EmbeddedId
  • @IdClass
  • @EmbeddedId

Here's a rough sketch of the EmbeddedIdway. I chose EmbeddedIdarbitrarily, but the choice between IdClassand EmbeddedIdis significant. You might choose differently.

这是EmbeddedId路线的粗略草图。我EmbeddedId随意选择,但在IdClass和之间的选择EmbeddedId很重要。你可能会做出不同的选择。

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

    // ...
 }

The parent entity needs one change: the userDetailsattribute mappedByshould be "id.eaihId". I think that's it, but I haven't used entities exactly like this before. Might have missed something... please post if you see errors.

父实体需要进行一项更改:userDetails属性mappedBy应为“id.eaihId”。我想就是这样,但我以前没有使用过完全像这样的实体。可能漏掉了一些东西……如果你看到错误,请发帖。

回答by Moni

I was also facing the same issue and followed this answer but it is not saving the child entity with parent entity. Here is the changes which I made and it is working fine. Make below changes -

我也遇到了同样的问题并遵循了这个答案,但它没有用父实体保存子实体。这是我所做的更改,并且工作正常。进行以下更改 -

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

While saving the parent entity set the parent object into the composite key like id.setInstance(parent entire obj)

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