用Hibernate映射双向列表 [英] Mapping a bidirectional list with Hibernate

查看:140
本文介绍了用Hibernate映射双向列表的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我不明白Hibernate在映射双向列表时的行为。 Hibernate产生的SQL语句对我来说似乎并不是最优的。有人可以启发我吗?

这种情况如下:我有一对多的父子关系。我将这种关系映射到一个双向列表。



根据

  @Entity 
public class Parent {

@Id @GeneratedValue private long id;
@Version private int version;
私人字符串名称;

@OneToMany(cascade = CascadeType.ALL)
@JoinColumn(name =parent_id,nullable = false)
@ org.hibernate.annotations.IndexColumn(name = parent_index)
List< Child> children = new ArrayList< Child>();

...

@实体
公共类子元素{

@Id @GeneratedValue private Long id;
@Version private int version;
私人字符串名称;

@ManyToOne
@JoinColumn(name =parent_id,updatable = false,insertable = false,nullable = false)
私有父亲;

...

但是在这种情况下,Hibernate会在产生三条SQL语句坚持一个孩子的父母:

  Hibernate:插入到Parent(name,version,id)values(?,?,? )
Hibernate:插入Child(名称,价格,版本,parent_id,parent_index,id)值(?,?,?,?,?,?)
Hibernate:更新子集parent_id =?, parent_index =?其中id =?

第三条语句似乎是多余的,因为 parent_id parent_index 似乎已经在第二个语句中设置了。



当我更改映射并重复像这样在父类中的 @JoinColumn 的声明属性' updatable = false,insertable = false

  @Entity 
public class Parent {

@Id @GeneratedValue private long id;
@Version private int version;
私人字符串名称;

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

...

@实体
公共类子元素{

@Id @GeneratedValue private Long id;
@Version private int version;
私人字符串名称;

@ManyToOne
@JoinColumn(name =parent_id,updatable = false,insertable = false,nullable = false)
私有父亲;

...

...然后Hibernate似乎产生更多优化SQL:
$ b $ pre $ Hibernate:插入Parent(name,version,id)values(?,?,?)
Hibernate:插入Child(名称,价格,版本,parent_id,parent_index,id)值(?,?,?,?,?,?)

客户端代码如下所示:

  EntityManagerFactory emf = Persistence.createEntityManagerFactory 测试); 
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参考指南不正确,还是我忽略了一些东西?

解决方案

好的,我没有仔细阅读注解参考指南足够。



2.2.5.3.1.1。双向它清楚地表明:

要将双向一对多映射为一对多,将一对多边作为拥有者,您必须删除mappedBy元素,并将多个一个@JoinColumn设置为可插入并可更新为false。 这个解决方案显然没有优化,并且会产生一些额外的UPDATE语句



重复第2.4.6.2.1节。与索引集合的双向关联

现在问题仍然存在:如果我重复@JoinColumn属性的'updatable = false'和'insertable = false'父(见第一篇文章中的代码)额外的更新声明似乎不会产生...这是一个合法的解决方法?或者这会导致另一个问题?


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: 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?

解决方案

Ok, I was not reading the Annotations Reference Guide thoroughly enough.

In Chapter 2.2.5.3.1.1. Bidirectional it is stated clearly:

To map a bidirectional one to many, with the one-to-many side as the owning side, you have to remove the mappedBy element and set the many to one @JoinColumn as insertable and updatable to false. This solution is obviously not optimized and will produce some additional UPDATE statements.

It probably would not hurt to repeat this information in Chapter 2.4.6.2.1. Bidirectional association with indexed collections .

Now the question remains: if I repeat the @JoinColumn attributes 'updatable = false' and 'insertable = false' on the Parent (see code in first post) the additional update statements seem not to get produced... is this a legitimate workaround? Or does this result in another problem?

这篇关于用Hibernate映射双向列表的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆