Hibernate Ленивая проблема инициализации - PullRequest
0 голосов
/ 03 августа 2011

, узнав немного о hibernate, я столкнулся с известным исключением отложенной инициализации в нижеприведенном случае.

У меня есть класс A, который имеет ссылку на другой класс B, и, используя hibernate, я пытался загрузить класс A, используя егоid и после закрытия сеанса я пытался напечатать некоторые свойства класса B, думая, что hibernate мог инициализировать объект, но все, что он сделал, это прокси-объект, вот фрагмент кода

Session session=HibernateUtil.getSessionFactory().openSession();
        Transaction tx = session.getTransaction();
        try {
            tx.begin();
            a=(A)session.load(A.class, "40288184318d9a3c01318d9a3eea0001");
            tx.commit();

        } catch (Exception e) {
            log.error("Unable to complete the transcation"
                    + "Transcation will be roll backed", e);
            e.printStackTrace();
            tx.rollback();

        } finally {
            log.info("Closing the session");
            if (session != null && session.isOpen() == true){
                session.close();
            }
        }
        System.out.println(a.getUuid());
        System.out.println(a.getB().getShortDescription());
        System.out.println(a.getB().getLongDescription());
        System.out.println(a.getB().getName());

этот коддавал мне org.hibernate.LazyInitializationException: could not initialize proxy - no Session, так как я знаю, что он дал мне только прокси для B, и когда я попытался получить свойства исключения B бросков hibernate

, я сделал небольшое изменение в своем коде, и это работало хорошо, вотизмененная версия

    Session session=HibernateUtil.getSessionFactory().openSession();
    Transaction tx = session.getTransaction();
    try {
        tx.begin();
        a=(A)session.load(A.class, "40288184318d9a3c01318d9a3eea0001");
        tx.commit();

    } catch (Exception e) {
        e.printStackTrace();
        tx.rollback();

    } finally {
        //log.info("Closing the session");
        if (session != null && session.isOpen() == true){
            b=des.getB();
            session.close();
        }
    }
    a.setB(b);
    System.out.println(a.getUuid());
    System.out.println(a.getB().getShortDescription());
    System.out.println(a.getB().getLongDescription());
    System.out.println(a.getB().getName());
}

, хотя она работает, но я не уверен, что это правильный подход или нет, пожалуйста, предложите

1 Ответ

3 голосов
/ 03 августа 2011

Определенно НЕ правильный подход.

Поймите, что вы хотите: вы хотите загрузить A, а затем получить все B, связанные с A. Поймите, что вы сделали: вы загрузили A, затем установите B на «b», что могло или не могло изменить значение B.

У вас есть несколько вариантов, чтобы сделать это правильно.

1) Используйте открытую сессию в виде фильтра в вашем приложении. Некоторые люди считают это анти-паттерном, но многие разработчики делают это, и я лично считаю, что это нормально.

2) Создайте пользовательский запрос, который за один раз предоставит вам все необходимое. Вы можете написать несколько hql, которые получат все B, связанные с A, когда вы получите A.

3) Звоните a.getB(), когда сеанс активен, и Hibernate получит его для вас.

4) Сделайте ассоциацию не ленивой, но я бы не стал этого делать, потому что она будет медленной. Если вам всегда нужен Bs, когда вы получаете A, тогда вы можете сделать это, но только в этом случае.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...