2010-07-24 2 views
8

У меня возникли проблемы с настройкой jpa-сопоставлений для некоторых объектов. У меня есть родительский объект, определенный следующим образом.jpa hibernate составное отображение внешнего ключа

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

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

+0

См http://stackoverflow.com/questions/2562746/jpa-entity-design-problem/ 2563009 # 2563009 – axtavt

ответ

12

Это регулируется 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

Спасибо, это работает по большей части. К сожалению, я не использую jpa 2.0, поэтому аннотация @MapsId недоступна. У меня это работает для вставок, удалив каскадное отношение из объекта userDetails родительского объекта. Поэтому мне необходимо вставить каждый дочерний элемент после сохранения родительского элемента, но теперь он работоспособен. – broschb

+0

@broschb Что вы используете? –

+0

jpa 1.0 spec. В настоящее время мне нужно использовать jboss 4.2.3, я понимаю, что jpa 2.0 не будет работать на этом сервере приложений, по крайней мере, не обмениваясь кучей библиотек. – broschb

0

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

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

Смежные вопросы