carmelolg
carmelolg

Reputation: 503

How nested FETCH JOIN works on Hibernate using JpaRepository and @Query annotation?

I have the following problem (pseudo-java-code):

Let me a class A,B,C with the following relationships:

@Entity
@Table(name = "A")
public class A {

  @OneToMany(mappedBy = "a")
  private B b; 

}


@Entity
@Table(name = "B")
public class B {

  @ManyToOne(fetch = FetchType.LAZY)
  @JoinColumn(name = "a_id")
  private A a;

  @OneToOne(mappedBy = "b", fetch = FetchType.LAZY)
  private C c;

}


@Entity
@Table(name = "C")
public class C {

  @OneToOne(fetch = FetchType.LAZY)
  @JoinColumn(name = "b_id")
  private B b;

}

I'm using JpaRepository with @Query annotation and I implemented the following query:

@Query("SELECT DISTINCT(a) FROM A a "
        + "LEFT JOIN FETCH a.b as b"
        + "WHERE a.id = :id ")
A findById(@Param("id") Integer id);

I want retrieve the informations about class A and B, but not C. Somehow (I don't know why) the query try to retrive also the relation between B and C. And then, with hibernate, start the lazy invocation for retrieving C.

Naturally, if I fetch also the relation between B and C (adding LEFT JOIN FETCH b.c as c) that's not happen.

My question is, why? Why I'm forced to fetch all nested relations and not only the ones which I need?

thank you. Carmelo

Upvotes: 3

Views: 937

Answers (2)

Zeromus
Zeromus

Reputation: 4532

Nullable @OneToOne relation are always eager fetched as explained in this post Making a OneToOne-relation lazy

Unconstrained (nullable) one-to-one association is the only one that can not be proxied without bytecode instrumentation. The reason for this is that owner entity MUST know whether association property should contain a proxy object or NULL and it can't determine that by looking at its base table's columns due to one-to-one normally being mapped via shared PK, so it has to be eagerly fetched anyway making proxy pointless.

Upvotes: 2

Tobb
Tobb

Reputation: 12205

Shot in the dark, but there are some issues with lazy-loading @OneToOne-relationships. At least in older versions of Hibernate. I think (but can't seem to find any documentation) that this was fixed in one of the newer versions, so if you are not using a new version of Hibernate, try upgrading.

Upvotes: 0

Related Questions