4
votes

I'm using JPA 2 and Hibernate 3. I noticed that calling EntityManager.merge() causes a SELECT on every referenced entity in the object graph PLUS inner joins between some of them.

Suppose you want to merge() a FooBar.

@Entity
public class FooBar {
    @ManyToOne
    private Foo foo;

    @ManyToOne
    private Bar bar;
}

@Entity
public class Foo {
    @ManyToOne
    private Baz baz;
}

@Entity
public class Bar {
    @ManyToOne
    private Baz baz;
}

If you do, Hibernate will issue a SELECT for each of FooBar, Foo, and Bar, and two for Baz. Then, it will issue a SELECT for Foo joined with Baz and another for Bar joined with Baz. Since I just wanted to merge a FooBar, I was expecting a single SELECT from it, but I ended up with a whopping 7 SELECT's!

First of all, is this normal? Second, if it is, is there a way to issue just a single SELECT?

Thanks.

1

1 Answers

5
votes

You are calling merge(..) with a detached object (i.e. one that is not associated with the session). What hibernate does here is - it loads an entity with the id of the passed object from the database and:

  • if no record is found, inserts the passed object
  • if an object is found, transfers all the fields and returns the persistent object

In the latter case a loading from the DB is involved, hence Hibernate needs to fetch the whole object. Hence the many selects.

You can try fetchType=LAZY for the ManyToOne relations (they are eager by default).