映射双向列表时我不理解休眠的行为。话Hibernate产生SQL语句似乎不是最佳的给我。有人可以告诉我吗?

的场景是以下:我有一个一对多父子关系。我映射与双向列表这种关系。

按照休眠批注参考指南(章:使用索引的集合)的映射双向关联应该是这样的:

@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_idparent_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();

我使用休眠-的EntityManager 3.4.0.GA。

我在想什么?就是Hibernate的参考指南不正确的,还是我忽视的东西?

有帮助吗?

解决方案

好,我没有读注解参考指南不够彻底。

在第 2.2.5.3。 1.1。双向的可以清楚地表示:

要映射的双向一对多,与所述一个对多侧作为持有端,则必须移除的mappedBy元件并设置多对一@JoinColumn作为可插入和可更新为假。的该解决方案显然是不优化,会产生一些附加的更新语句

它可能不会伤害到重复的第2.4.6.2.1。与索引的集合的双向关联。

现在的问题是:如果我重复@JoinColumn属性“更新=假”和“插入=假”的父母(见第一邮编)额外的更新语句似乎并没有得到生产...这是一个合法的解决方法吗?或者处于另一个问题这样的结果?

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top