составное отображение внешнего ключа jpa hibernate - PullRequest
9 голосов
/ 24 июля 2010

У меня проблемы с настройкой сопоставлений 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, но я не уверен, как это сделать, когда одно поле является внешним ключом для родительского класса. И как только это будет настроено, как родитель будет ссылаться на дочернюю сущность?

Любая помощь приветствуется.

Ответы [ 2 ]

13 голосов
/ 24 июля 2010

Это регулируется JPA 2 spec разделом 2.4.1, «Первичные ключи, соответствующие производным идентификаторам». Этот раздел содержит два примера, непосредственно применимых к вашей проблеме.

Как описано в спецификации, в этом случае существует два способа представления ключа дочерней сущности:

  • @IdClass
  • @EmbeddedId

Вот примерный набросок пути 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;

    // ...
 }

Родительской сущности требуется одно изменение: атрибут userDetails mappedBy должен быть "id.eaihId". Я думаю, что это так, но я раньше не использовал точно такие же объекты. Возможно, что-то пропустил ... пожалуйста, напишите, если вы видите ошибки.

0 голосов
/ 23 марта 2017

Я также столкнулся с той же проблемой и следовал этому ответу, но он не сохраняет дочернюю сущность с родительской сущностью.Вот изменения, которые я сделал, и это работает нормально.Внесите изменения ниже -

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...