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?
The scenario is the following: I have a one-to-many parent-child relationship. I map this relationship with a bidirectional list.
According to the Hibernate Annotation Reference Guide (Chapter 2.4.6.2.3. Bidirectional association with indexed collections) the mapping should look like this:
@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<Child> children = new ArrayList<Child>();
...
@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;
...
But in this case Hibernate produces three SQL statements when persisting a parent with one child:
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=?
The third statement seems to be redundant, because parent_id and parent_index seem to be set already in the second statement.
When I change the mapping and repeat the attributes 'updatable = false, insertable = false' to the declaration of the @JoinColumn in the Parent like this:
@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<Child> children = new ArrayList<Child>();
...
@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;
...
...then Hibernate seems to produce much more optimized SQL:
Hibernate: insert into Parent (name, version, id) values (?, ?, ?)
Hibernate: insert into Child (name, price, version, parent_id, parent_index, id) values (?, ?, ?, ?, ?, ?)
The client code looks like this:
    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();
I am using hibernate-entitymanager 3.4.0.GA.
What am I missing? Is the Hibernate Reference Guide not correct, or am I overlooking something?