我不明白映射双向列表时Hibernate的行为。 Hibernate产生的SQL语句对我来说似乎并不是最优的。有人可以启发我吗?用休眠映射双向列表
该场景如下:我有一对多的亲子关系。我将这种关系映射到双向列表。
按照Hibernate Annotation Reference Guide(章:使用索引的集合双向关联)的映射应该是这样的:
@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;
...
但在这种情况下,休眠产生持续一个孩子父母时,三个SQL语句:
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=?
第三条语句似乎是多余的,因为parent_id
和parent_index
似乎已经在第二条语句中设置。
当我改变映射和重复属性“更新=假,可插入=假”到@JoinColumn的声明在家长是这样的:
@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;
...
...然后休眠似乎产生更优化的SQL:
Hibernate: insert into Parent (name, version, id) values (?, ?, ?)
Hibernate: insert into Child (name, price, version, parent_id, parent_index, id) values (?, ?, ?, ?, ?, ?)
客户端代码如下所示:
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();
我正在使用hibernate-entitymanager 3.4.0.GA.
我错过了什么? “Hibernate参考指南”不正确,还是我忽略了某些内容?