为什么hibernate会为OneToMany映射生成插入和更新

时间:2014-08-19 08:40:15

标签: java hibernate jpa

我试图用一个小例子来理解Hibernate中的一对多映射。我有一个Product,其中包含一组Part's。这是我的实体类:

Part.java

@Entity
public class Part {
    @Id
    @GeneratedValue
    int id;
    String partName;
    //Setters & Getters
}

Product.java

@Entity
public class Product {
    private String serialNumber;
    private Set<Part> parts = new HashSet<Part>();
    @Id
    public String getSerialNumber() {
        return serialNumber;
    }
    @OneToMany
    @JoinColumn(name = "PRODUCT_ID")
    public Set<Part> getParts() {
        return parts;
    }
    // Setter methods
}

然后我尝试在我的数据库中保存一些部件和产品,并观察下面由hibernate生成的查询:

Hibernate: insert into Product (serialNumber) values (?)
Hibernate: insert into Part (partName, id) values (?, ?)
Hibernate: update Part set PRODUCT_ID=? where id=?

这里要在Part表中添加记录,hibernate会生成2个DML操作 - insertupdate。如果单个insert命令足以在表中添加记录,那么为什么hibernate在这种情况下使用插入和更新?请解释一下。

4 个答案:

答案 0 :(得分:3)

我知道这很疯狂,但我有同样的问题,谷歌把我带到了这里,所以在修好之后我想我应该发一个答案。

如果你使连接列不可为空且不可更新,Hibernate会将插入/更新方法切换为直接插入,我认为在你的情况下它不是任何方式:

@JoinColumn(name = "PRODUCT_ID", nullable = false, updatable = false)

答案 1 :(得分:0)

如果Part为复合元素列表,那么只会有两个查询。请检查并恢复。

如果它不是复合元素,hibernate会尝试将个体作为单独的查询插入,并尝试在它们之间创建关系。

在早期的情况下,hibernate将使用关系键插入。

答案 2 :(得分:-1)

** Hibernate:插入Product(serialNumber)值(?)

Hibernate:插入Part(partName,id)值(?,?)**

在这两个查询中,hibernate只是将记录插入数据库。 在那个阶段,hibernate没有在两个实体之间创建任何关系。

Hibernate:更新部件集PRODUCT_ID =?其中id =?

现在制作实体表后,hibernate将在两者之间建立关系 通过使用上面的第三个查询...

答案 3 :(得分:-1)

该关联是单向的,因此Product是拥有方(因为它是唯一的一方)。

使关联成为双向关联,并使Part成为关联所有者。这样您就可以避免冗余更新,因为外键值将被指定为Part的插入语句的一部分。