Why does TypedQuery.getResultList () allow each ManyToOne association with a separate SELECT?

Given the following simple entity association: (EntityA) * -1 (EntityB) made in a database with a foreign key in EntityA (entityB_id).

JPA entities map this relation unidirectionally:

@Entity
EntityA {
    @Id
    @GeneratedValue
    private long id;

    @Column(nullable=false,length=250)
    private String name;

    @ManyToOne(optional=false)
    private EntityB entityB;

    ... getter/setter ...
}

@Entity
EntityB {
    @Id
    @GeneratedValue
    private long id;

    @Column(nullable=false,length=250)
    private String name;

    ... getter/setter ...
}

If a simple query is executed:

EntityManager em = ...;
TypedQuery<EntityA> tq = em.createQuery("from EntityA a", EntityA.class);
tq.getResultList();

I see in the output of SQL debug Hibernate that an EntityB query is executed for each EntityA line:

Hibernate: 
    select
        entitya0_.id as id8_,
        entitya0_.entityB_id as entityB3_8_,
        entitya0_.name as name8_ 
    from
        EntityA entitya0_
Hibernate: 
    select
        entityb0_.id as id4_0_,
        entityb0_.name as name4_0_ 
    from
        EntityB entityb0_ 
    where
        entityb0_.id=?

Even if the default fetching strategy is EAGER (this seems to be the case), EntityB needs to be retrieved through implizit join, right? What's wrong?

But it gets even weirder - if only one EntityA object is loaded:

EntityA a = em.find(EntityA.class, new Long(1));

Then Hibernate seems to understand the work:

Hibernate: 
    select
        entitya0_.id as id1_1_,
        entitya0_.entityB_id as entityB3_1_1_,
        entitya0_.name as name1_1_,
        entityb1_.id as id12_0_,
        entityb1_.name as name12_0_ 
    from
        EntityA entitya0_ 
    inner join
        EntityB entityb1_ 
        on entitya0_.entityB_id=entityb1_.id 
    where
        entitya0_.id=?

The above tests were performed using Hibernate 3.5 and JPA 2.0.

+5
3

, , , fetch:

select a from entityA left join fetch a.entityB

EntityB ( FetchType.LAZY).

+3

- EAGER (, ), EntityB , ? ?

, FetchType ManyToOne EAGER. , One , Many, . ( JPA ).

Hibernate Fetch, . :

2.4.5.1.

JPA , Hibernate , . , :

  • [...]

  • @Fetch: , . FetchMode SELECT (a select is , ), SUBSELECT ( , - , ) JOIN ( SQL JOIN ). JOIN ( , JOIN ).

, ( ):

@ManyToOne(optional=false)
@Fetch(FetchMode.JOIN)
private EntityB entityB;
+4

, ? ORM , . , , .

, Hibernate , - ManyToOne. , EntityBs, , EntityAs . EntityB , , .

0

All Articles