Учитывая следующую простую ассоциацию сущностей: (EntityA) * -1 (EntityB), созданный в базе данных с внешним ключом в EntityA (entityB_id).
Объекты JPA отображают эту связь однонаправленно:
@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 ...
}
Если сделан простой запрос:
EntityManager em = ...;
TypedQuery<EntityA> tq = em.createQuery("from EntityA a", EntityA.class);
tq.getResultList();
В выводе отладки SQL Hibernate я вижу, что запрос EntityB выполняется для каждой строки EntityA:
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=?
Даже если стратегией выборки по умолчанию является EAGER (что, похоже, имеет место), EntityB следует извлекать через соединение implizit, не так ли?Что не так?
Но это становится еще более странным - если загружен только один объект EntityA:
EntityA a = em.find(EntityA.class, new Long(1));
Тогда Hibernate, кажется, понимает работу:
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=?
Вышеупомянутые тесты были сделаны с Hibernate 3.5 и JPA 2.0.