Внешний ключ не хранится в дочерней сущности (один-ко-многим)
Я совершенно новичок в спящем режиме и наткнулся на эту проблему, для которой я не могу найти решение.
при сохранении родительского объекта (с один-ко-многим отношение с дочерним), внешний ключ к этому родителю не хранится в таблице ребенка.
мои занятия:
родитель.java
@javax.persistence.Table(name = "PARENT")
@Entity
public class PARENT {
private Integer id;
@javax.persistence.Column(name = "ID")
@Id
@GeneratedValue(strategy=GenerationType.AUTO)
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
private Collection<Child> children;
@OneToMany(mappedBy = "parent", fetch = FetchType.EAGER, cascade = {CascadeType.ALL})
@Cascade({org.hibernate.annotations.CascadeType.ALL})
public Collection<Child> getChildren() {
return children;
}
public void setChildren(Collection<Child> children) {
this.children = children;
}
}
ребенок.java
@javax.persistence.Table(name = "CHILD")
@Entity
@IdClass(Child.ChildId.class)
public class Child {
private String childId1;
@Id
public String getChildId1() {
return childId1;
}
public void setChildId1(String childId1) {
this.childId1 = childId1;
}
private String childId2;
@Id
public String getChildId2() {
return childId2;
}
public void setChildId2(String childId2) {
this.childId2 = childId2;
}
private Parent parent;
@ManyToOne
@javax.persistence.JoinColumn(name = "PARENT_ID", referencedColumnName = "ID")
public Parent getParent() {
return parent;
}
public void setParent(Operation parent) {
this.parent = parent;
}
public static class ChildId implements Serializable {
private String childId1;
@javax.persistence.Column(name = "CHILD_ID1")
public String getChildId1() {
return childId1;
}
public void setChildId1(String childId1) {
this.childId1 = childId1;
}
private String childId2;
@javax.persistence.Column(name = "CHIILD_ID2")
public String getChildId2() {
return childId2;
}
public void setChildId2(String childId2) {
this.childId2 = childId2;
}
public ChildId() {
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
ChildId that = (ChildId) o;
if (childId1 != null ? !childId1.equals(that.childId1) : that.childId1 != null)
return false;
if (childId2 != null ? !childId2.equals(that.childId2) : that.childId2 != null)
return false;
return true;
}
@Override
public int hashCode() {
int result = childId1 != null ? childId1.hashCode() : 0;
result = 31 * result + (childId2 != null ? childId2.hashCode() : 0);
return result;
}
}
}
5 ответов
вы также можете добавить дополнительный метод к своему родителю, как
public void addChild(Child child)
что делает что-то вроде
child.setParent(this);
У меня есть хорошее решение для этого случая: D
mappedBy означает inverse = "true" . так что вы должны inverse = "false"
попробовать его..
@OneToMany(fetch = FetchType.EAGER, cascade ={CascadeType.ALL})//javax.persistent.CascadeType
@JoinColumn(name = "parent_id")//parent's foreign key
public Collection<Child> getChildren() {
return children;
}
Я надеюсь, что это хорошо будет работать
проблема в том, что в test1 () вы сохраняете ребенка перед сохранением родителя. В test2 () вы сначала сохраняете родителя, затем ребенка, что является правильным и поэтому работает.
подумайте об этом таким образом. Можете ли вы родиться раньше, чем родятся ваши мать и отец? Нет, они должны существовать прежде, чем ты сможешь существовать. Поместите родителя, затем ребенка, как в test2 ().
Если вы хотите, вы можете редактировать вас parentDAO.save () для сохранения или обновления любых ссылочных детей. Таким образом, они экономят с 1 звонка.
перед сохранением родителя ему не был назначен идентификатор. Таким образом, когда вы сначала сохраняете ребенка, у него нет внешнего ключа для сохранения. Вы хотите сделать это как test2 (), но обернуть в транзакцию. Взгляните здесь. Я думаю, что раздел под названием "демаркация транзакций с EJB / CMT" может быть тем, что вы хотите.
основная проблема в test1 () заключается в том, что вы не устанавливаете parent в дочернем объекте. ты должен сказать.. ребенок.setparent осуществляет(родителя). просто установка child в parent не означает, что ребенок знает о родителе. на самом деле, его ребенок, который владеет отношениями. таким образом, необходимо установить parent в дочернем объекте. последовательность вызова saveorUpdate () для родителя или ребенка не имеет значения.
test2 () работает, потому что вы установили parent в дочернем объекте, вызвав child.setparent осуществляет(). Этого не хватает в test1().