Я являюсь довольно новым для спящего режима и наткнулся на эту проблему, для которой я не могу найти решение.
При сохранении родительского объекта (со связью "один ко многим" с ребенком), внешний ключ к этому родителю не хранится в таблице ребенка.
Мои классы:
@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;
}
}
@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;
}
}
}
public class Test() {
private ParentDao parentDao;
public void setParentDao(ParentDao parentDao) {
this.parentDao = parentDao;
}
private ChildDao childDao;
public void setChildDao(ChildDao childDao) {
this.childDao = parentDao;
}
test1() {
Parent parent = new Parent();
Child child = new Child();
child.setChildId1("a");
child.setChildId2("b");
ArrayList<Child> children = new ArrayList<Child>();
children.add(child);
parent.setChildren(children);
parent.setValue("value");
parentDao.save(parent); //calls hibernate's currentSession.saveOrUpdate(entity)
}
test2() {
Parent parent = new Parent();
parent.setValue("value");
parentDao.save(parent); //calls hibernate's currentSession.saveOrUpdate(entity)
Child child = new Child();
child.setChildId1("a");
child.setChildId2("b");
child.setParent(parent);
childDao.save(); //calls hibernate's currentSession.saveOrUpdate(entity)
}
}
При вызове test1 (), оба объекта записаны в базу данных, но поле PARENT_ID в Дочерней таблице остается пустым.
Единственное обходное решение, которое я имею до сих пор, является test2 () - сохраняющий родителя сначала и затем ребенка.
Моя цель состоит в том, чтобы сохранить родителя и его детей в одном вызове для сохранения () на Родителе. Какие-либо идеи?
Вы также можете добавить к своему родителю дополнительный метод, например
public void addChild(Child child)
, который выполняет что-то вроде
child.setParent(this);
Проблема в том, что в test1 () вы сохраняете дочерний элемент перед сохранением родителя. В test2 () вы сначала сохраняете родителя, а затем потомка, что правильно, и поэтому оно работает.
Подумайте об этом иначе. Можете ли вы родиться раньше, чем родятся ваши мать и отец? Нет, они должны существовать, прежде чем вы сможете существовать. Создайте контейнер для родителя, а затем для потомка, как в test2 ().
При желании вы можете отредактировать parentDAO.save (), чтобы сохранить или обновить любые дочерние элементы, на которые есть ссылки. Таким образом они экономят с 1 звонком.
Перед сохранением родительского элемента ему не был назначен идентификатор. Итак, когда вы сначала сохраняете ребенка, у него нет внешнего ключа для сохранения. Вы хотите сделать это как test2 (), но завершить транзакцию. Взгляните здесь . Я думаю, что раздел под названием «Разграничение транзакций с помощью EJB / CMT» может быть тем, что вам нужно.