title: Mapping a bidirectional list with Hibernate
body: <p>I don't understand the behavior of Hibernate when mapping a bidirectional list. The SQL statements that Hibernate produces seem not optimal to me. Can somebody enlighten me?</p>
  
  <p>The scenario is the following: I have a one-to-many parent-child relationship. I map this relationship with a bidirectional list.</p>
  
  <p>According to the <a href="http://docs.jboss.org/hibernate/annotations/3.5/reference/en/html_single/" rel="nofollow noreferrer">Hibernate Annotation Reference Guide</a> (Chapter: Bidirectional association with indexed collections) the mapping should look like this:</p>
  
  <pre><code>@Entity
  public class Parent {
  
      @Id  @GeneratedValue private long id;
      @Version  private int version;
      private String name;
  
      @OneToMany(cascade = CascadeType.ALL)
      @JoinColumn(name = "parent_id", nullable=false)
      @org.hibernate.annotations.IndexColumn(name = "parent_index")
      List&lt;Child&gt; children = new ArrayList&lt;Child&gt;();
  
  ...
  
  @Entity
  public class Child {
  
      @Id @GeneratedValue private Long id;
      @Version private int version;
      private String name;
  
      @ManyToOne
      @JoinColumn(name = "parent_id", updatable = false, insertable = false, nullable=false)
      private Parent parent;
  
  ...
  </code></pre>
  
  <p>But in this case Hibernate produces three SQL statements when persisting a parent with one child:</p>
  
  <pre><code>Hibernate: insert into Parent (name, version, id) values (?, ?, ?)
  Hibernate: insert into Child (name, price, version, parent_id, parent_index, id) values (?, ?, ?, ?, ?, ?)
  Hibernate: update Child set parent_id=?, parent_index=? where id=?
  </code></pre>
  
  <p>The third statement seems to be redundant, because <code>parent_id</code> and <code>parent_index</code> seem to be set already in the second statement.</p>
  
  <p>When I change the mapping and repeat the attributes '<em>updatable = false, insertable = false</em>' to the declaration of the <em>@JoinColumn</em> in the Parent like this:</p>
  
  <pre><code>@Entity
  public class Parent {
  
      @Id  @GeneratedValue private long id;
      @Version  private int version;
      private String name;
  
      @OneToMany(cascade = CascadeType.ALL)
      @JoinColumn(name = "parent_id", updatable = false, insertable = false, nullable=false)
      @org.hibernate.annotations.IndexColumn(name = "parent_index")
      List&lt;Child&gt; children = new ArrayList&lt;Child&gt;();
  
  ...
  
  @Entity
  public class Child {
  
      @Id @GeneratedValue private Long id;
      @Version private int version;
      private String name;
  
      @ManyToOne
      @JoinColumn(name = "parent_id", updatable = false, insertable = false, nullable=false)
      private Parent parent;
  
  ...
  </code></pre>
  
  <p>...then Hibernate seems to produce much more optimized SQL:</p>
  
  <pre><code>Hibernate: insert into Parent (name, version, id) values (?, ?, ?)
  Hibernate: insert into Child (name, price, version, parent_id, parent_index, id) values (?, ?, ?, ?, ?, ?)
  </code></pre>
  
  <p>The client code looks like this:</p>
  
  <pre><code>    EntityManagerFactory emf = Persistence.createEntityManagerFactory("test");
      EntityManager em = emf.createEntityManager();
      EntityTransaction tx = em.getTransaction();
      tx.begin();
  
      Parent newParent = new Parent();
      newParent.setName("Parent1");
  
      Child newChild = new Child();
      newChild.setName("Child1");
  
      newParent.getChildren().add(newChild);
      newChild.setParent(newParent);
  
      em.persist(newParent);
  
      em.flush();
      tx.commit();
  </code></pre>
  
  <p>I am using hibernate-entitymanager 3.4.0.GA.</p>
  
  <p>What am I missing? Is the Hibernate Reference Guide not correct, or am I overlooking something?</p>