当前位置:  开发笔记 > 编程语言 > 正文

使用Hibernate映射双向列表

如何解决《使用Hibernate映射双向列表》经验,为你挑选了1个好方法。

我不了解映射双向列表时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 children = new ArrayList();

...

@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;

...

但是在这种情况下,Hibernate在持有一个子节点的父节点时会生成三个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_idparent_index似乎在第二份声明已设置.

当我更改映射并将属性' updatable = false,insertable = false ' 重复到Parent中@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 children = new ArrayList();

...

@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;

...

...然后Hibernate似乎产生了更多优化的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参考指南不正确,还是我忽略了什么?



1> jbandi..:

好的,我没有仔细阅读"注释参考指南".

在第2.2.5.3.1.1节中.双向说明清楚:

要将双向一个映射到多个,以一对多方作为拥有方,您必须删除mappedBy元素并将多个@JoinColumn设置为可插入且可更新为false.此解决方案显然未经过优化,并将生成一些额外的UPDATE语句.

重复第2.4.6.2.1节中的这些信息可能不会有什么坏处.与索引集合的双向关联.

现在问题仍然存在:如果我在Parent上重复@JoinColumn属性'updatable = false'和'insertable = false'(请参阅第一篇文章中的代码),其他更新语句似乎不会产生...这是一个合法的解决方法?或者这会导致另一个问题吗?

推荐阅读
手机用户2402851335
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有