20

I am trying to understand the one-to-many mapping in Hibernate with a small example. I have a Product with a set of Part's. Here are my entity classes:

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
}

Then I tried to save some parts and products in my database and observed below queries generated by hibernate:

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

Here to add a record in Part table, hibernate generates 2 DML operations - insert and update. If a single insert command is sufficient to add a record in table then why hibernate uses both insert and update in this case? Please explain.

Chaitanya
  • 15,403
  • 35
  • 96
  • 137

4 Answers4

15

I know this is crazy old but I had the same problem and Google brought me here, so after fixing it I figured I should post an answer.

Hibernate will switch the insert/update approach to straight inserts if you make the join column not nullable and not updatable, which I assume in your case it is neither anyways:

@JoinColumn(name = "PRODUCT_ID", nullable = false, updatable = false)
marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459
GhostBytes
  • 542
  • 5
  • 11
  • 1
    Does setting `updatable=false` mean that if `Product` and it's `Part`s are updated later by calling `saveOrUpdate`, then `Part`s will not be updated in the DB? – Peter Nov 19 '18 at 16:43
  • No. It simply means that column is not updatable once the entry is made. Updates on other columns, depending on their definition of course, will still occur as normal. – GhostBytes Nov 23 '18 at 14:13
  • 1
    Just a heads up: while this indeed removed the extra `UPDATE` calls, since I am using EclipseLink's `batch-writing`, it has also split my `INSERT INTO` calls and thus resulted in worse performance. – payne Nov 26 '21 at 19:31
0

If Part as composite element list then only two query will come. Please check and revert.

If its not a composite element , hibernate try to insert individual as a separate query and it will try to create relationship between them.

In earlier case hibernate will insert with relationship key.

Siva Kumar
  • 1,983
  • 3
  • 14
  • 26
-1

**Hibernate: insert into Product (serialNumber) values (?)

Hibernate: insert into Part (partName, id) values (?, ?)**

In these two queries hibernate is simply inserting a record into the database. At that stage hibernate is not creating any relationship between the two entities.

Hibernate: update Part set PRODUCT_ID=? where id=?

Now after making entity tables,hibernate is going to make a relationship between the two by using the above third query...

-1

The association is uni-directional, so Product is the owning side (because it's the only side).

Make the association bidirectional and make Part the association owner. That way you will avoid redundant updates because the foreign key values will be specified as part of insert statements for Part.

Dragan Bozanovic
  • 23,102
  • 5
  • 43
  • 110