title: jpa recursive persistence depth - saving nested objects
body: <p>I'm trying to understand the right way to handle persisting objects with JPA.  I created four related objects, each owns a <code>Set&lt;?&gt;</code> of the children.  I added bidirectional mappings.  I created a test where I added one of each up the chain and then tried to persist the set.  It appears I can't go beyond an immediate relationship.  Is that the case?  Is it expected I have to build a service for each object that performs the adding of a child to a parent rather than directly using the accessors?</p>
  
  <p>Ok, let's say I have these objects:</p>
  
  <pre><code>@Entity
  public class A implements Serializable
  {
      @Id
      @GeneratedValue
      private Long id;
  
      @OneToMany(targetEntity = B.class
              , mappedBy = "a"
              , cascade = CascadeType.ALL
              , fetch = FetchType.LAZY
      )
      private Set&lt;B&gt; bs;
  }
  
  @Entity
  public class B implements Serializable
  {
      @Id
      @GeneratedValue
      private Long id;
  
      @ManyToOne(optional = false
              , cascade = CascadeType.ALL)
      @JoinColumn(name = "a_id", referencedColumnName = "id")
      private A a;
  
      @OneToMany(targetEntity = C.class
              , mappedBy = "b"
              , cascade = CascadeType.ALL
              , fetch = FetchType.LAZY
      )
      private Set&lt;C&gt; cs;
  }
  
  @Entity
  public class C implements Serializable
  {
      @Id
      @GeneratedValue
      private Long id;
  
      @ManyToOne(optional = false
              , cascade = CascadeType.ALL)
      @JoinColumn(name = "b_id", referencedColumnName = "id")
      private B b;
  
      @OneToMany(targetEntity = D.class
              , mappedBy = "c"
              , cascade = CascadeType.ALL
              , fetch = FetchType.LAZY
      )
      private Set&lt;D&gt; ds;
  }
  
  @Entity
  public class D implements Serializable
  {
      @Id
      @GeneratedValue
      private Long id;
  
      @ManyToOne(optional = false
              , cascade = CascadeType.ALL)
      @JoinColumn(name = "c_id", referencedColumnName = "id")
      private C c;
  }
  </code></pre>
  
  <p>And, then I create one of each and add it to the previous relative:</p>
  
  <pre><code>    A a = new A();
      B b = new B();
      a.getBs().add(b);
      C c = new C();
      b.getCs().add(c);
      D d = new D();
      c.getDs().add(d);
  </code></pre>
  
  <p>If I then persist it (<code>dService.save(d);</code>) it fails because C's id doesn't exist.  Since the value has to be generated by saving it, I would have expected it to recursively travel up the change and save A first, and then fill in from there.  If I start with A (<code>aService.save(a);</code>) I get the same error on B.  It behaves like there's no cascade.</p>