2013-09-27 4 views
0

Я знаю, что есть много вопросов о присоединении к объединению. Разница объясняется, как показано ниже:Join vs join fetch

А «выборка» присоединиться позволяет ассоциации или коллекции значений для инициализации вместе с их объекты с помощью одного выбора. Это особенно полезно в случае коллекции. Он эффективно отменяет внешнее объединение и ленивые объявления файла сопоставления для ассоциаций и коллекций.

Однако, когда у меня есть критерии или HQL, который использует внутренние или внешнее соединение не извлекая, я заметил, что лица, кажется, полностью неправдоподобными (мое отображение зимует использовать FetchType.LAZY). Я только ожидал этого, когда пишу 'join fetch'. Так что я не вижу разницы в этом случае.

Должно быть, что-то здесь отсутствует. Может ли кто-нибудь помочь мне прояснить это, пожалуйста?

UPDATE

StringBuilder hql = new StringBuilder(); 
hql.append("select question ") 
    .append("from User as user ") 
    .append("left join user.definition as definition ") 
    .append("left join definition.sections as section ") 
    .append("left join section.questions as question ") 
    .append("where user.id = :user"); 

Query query = getQuery(hql.toString()); 
query.setParameter("user.id", userId); 

return query.list(); 

Когда я осмотреть первый пункт списка вопросов я получаю следующее:

ссылки класса
questions = {[email protected]} size = 18 
[0]={[email protected]}"[email protected][]" 
    section = {[email protected]}"[email protected][]" 
     handler = {[email protected]} 
      interfaces = {java.lang.Class[1]@6897} 
      constructed = true 
      persistentClass = {[email protected]}"class model.Section" 
      getIdentifierMethod = null 
      setIdentifierMethod = null 
      overridesEquals = true 
      componentIdType = null 
      replacement = null 
      entityName = {[email protected]}"model.Section" 
      id = {[email protected]}"1" 
      target = {[email protected]}"[email protected][]" 
       name = {[email protected]}"General" 
       sequence = 1 
       textStart = {[email protected]}"Some value" 
       textEnd = null 
       sectionVersion = 1 
       status = {[email protected]}"ACTIVE" 
       definitions = {[email protected]} size = 1 
       questions = {[email protected]} size = 13 
       validFrom = {[email protected]}"2012-01-01 00:00:00.0" 
       validTo = {[email protected]}"2099-01-01 00:00:00.0" 
       active = false 
       uuid = {[email protected]}"97277496-12ee-453d-9478-9fc4e1519c02" 
       id = {[email protected]}"1" 
       version = {[email protected]}"1" 
       initialized = true 
       readOnly = false 
       unwrap = false 
       session =  {[email protected]}"SessionImpl(PersistenceContext[entityKeys= [EntityKey[model.PossibleAnswer#57], EntityKey[model.PossibleAnswer#56], EntityKey[PossibleAnswer#59], E...readOnlyBeforeAttachedToSession = null sessionFactoryUuid = null specjLazyLoad = false 

вопрос к это раздел, в StackTrace вы можете увидеть что раздел полностью загружен, хотя я не указал «join fetch» ​​в своем HQL.

+1

Покажите нам код и объясните, как вы проверяете, что коллекция охотно/лениво взята. –

+0

Пожалуйста, см. Больше в моем исходном вопросе – user2054927

ответ

2

Не используйте отладчик, чтобы проверить, инициализирован ли объект. Отладчик вызовет методы ваших объектов за вашей спиной, чтобы показать содержимое объекта, и вызов этих методов будет инициализировать объект.

Используйте Hibernate.isInitialized(question.getSection()), чтобы проверить, инициализирован ли сеанс.

+0

Возможно, вы хотели использовать question.getSection() вместо getSession()? Я тестировал с getQuestion(), getSession() и getSection(). GetDefinitions(). Я получил «true», «false», «false» соответственно. Спасибо, что указали, что лучше не использовать отладчик для этого материала. Существуют ли другие возможности, которые я могу использовать для такого рода вещей? – user2054927

+0

Да, вот что я имел в виду. Извините за путаницу. Нет, что я знаю. Hibernate.isInitialized предназначен именно для этого. –