Внешний ключ не хранится в дочерней сущности (один-ко-многим)

Я совершенно новичок в спящем режиме и наткнулся на эту проблему, для которой я не могу найти решение.

при сохранении родительского объекта (с один-ко-многим отношение с дочерним), внешний ключ к этому родителю не хранится в таблице ребенка.

мои занятия:

родитель.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().