org.hibernacja.LazyInitializationException - could not initialize proxy-no Session

Otrzymuję następujący wyjątek:

Exception in thread "main" org.hibernate.LazyInitializationException: could not initialize proxy - no Session
    at org.hibernate.proxy.AbstractLazyInitializer.initialize(AbstractLazyInitializer.java:167)
    at org.hibernate.proxy.AbstractLazyInitializer.getImplementation(AbstractLazyInitializer.java:215)
    at org.hibernate.proxy.pojo.javassist.JavassistLazyInitializer.invoke(JavassistLazyInitializer.java:190)
    at sei.persistence.wf.entities.Element_$$_jvstc68_47.getNote(Element_$$_jvstc68_47.java)
    at JSON_to_XML.createBpmnRepresantation(JSON_to_XML.java:139)
    at JSON_to_XML.main(JSON_to_XML.java:84)

Kiedy próbuję wywołać z main następujące linie:

Model subProcessModel = getModelByModelGroup(1112);
System.out.println(subProcessModel.getElement().getNote());

Zaimplementowałem metodę getModelByModelGroup(int modelgroupid) najpierw tak:

    public static Model getModelByModelGroup(int modelGroupId, boolean openTransaction) {

        Session session = SessionFactoryHelper.getSessionFactory().getCurrentSession();     
        Transaction tx = null;

        if (openTransaction)
            tx = session.getTransaction();

        String responseMessage = "";

        try {
            if (openTransaction)            
                tx.begin();
            Query query = session.createQuery("from Model where modelGroup.id = :modelGroupId");
            query.setParameter("modelGroupId", modelGroupId);
            @SuppressWarnings("unchecked")
            List<Model> modelList = (List<Model>)query.list(); 
            Model model = null;
            // Cerco il primo Model che è in esercizio: idwf_model_type = 3
            for (Model m : modelList)
                if (m.getModelType().getId() == 3) {
                    model = m;
                    break;
                }

            if (model == null) {
                Object[] arrModels = modelList.toArray();
                if (arrModels.length == 0) 
                    throw new Exception("Non esiste ");

                model = (Model)arrModels[0];
            }

            if (openTransaction)
                tx.commit();
            return model;

        } catch(Exception ex) {
            if (openTransaction)
                tx.rollback();
            ex.printStackTrace();
            if (responseMessage.compareTo("") == 0)
                responseMessage = "Error" + ex.getMessage();
            return null;        
        }

I dostał wyjątek. Następnie przyjaciel zasugerował mi, aby zawsze testować sesję i uzyskać bieżącą sesję, aby uniknąć tego błędu. Więc zrobiłem to:

public static Model getModelByModelGroup(int modelGroupId) {

        Session session = null;
        boolean openSession = session == null;
        Transaction tx = null;
        if (openSession){
          session = SessionFactoryHelper.getSessionFactory().getCurrentSession();   
            tx = session.getTransaction();
        }
        String responseMessage = "";

        try {
            if (openSession)            
                tx.begin();
            Query query = session.createQuery("from Model where modelGroup.id = :modelGroupId");
            query.setParameter("modelGroupId", modelGroupId);
            @SuppressWarnings("unchecked")
            List<Model> modelList = (List<Model>)query.list(); 
            Model model = null;
            for (Model m : modelList)
                if (m.getModelType().getId() == 3) {
                    model = m;
                    break;
                }

            if (model == null) {
                Object[] arrModels = modelList.toArray();
                if (arrModels.length == 0) 
                    throw new RuntimeException("Non esiste");

                model = (Model)arrModels[0];

            if (openSession)
                tx.commit();
            return model;

        } catch(RuntimeException ex) {
            if (openSession)
                tx.rollback();
            ex.printStackTrace();
            if (responseMessage.compareTo("") == 0)
                responseMessage = "Error" + ex.getMessage();
            return null;        
        }

    }

Ale nadal otrzymujemy ten sam błąd. Czytałem dużo na ten błąd i znalazłem kilka możliwych rozwiązań. Jednym z nich było ustawienie lazyLoad na false, ale nie wolno mi tego robić, dlatego zasugerowano mi kontrolowanie sesji

Author: Rubens Mariuzzo, 2014-02-05

15 answers

Błędem jest to, że Konfiguracja zarządzania sesją jest ustawiona na zamknięcie sesji podczas zatwierdzania transakcji. Sprawdź czy masz coś takiego:

<property name="current_session_context_class">thread</property> 

W Twojej konfiguracji.

Aby rozwiązać ten problem, można zmienić konfigurację fabryki sesji lub otworzyć inną sesję i tylko wtedy poprosić o te leniwe ładowane obiekty. Ale sugerowałbym tutaj zainicjowanie tej leniwej kolekcji w getModelByModelGroup i wywołanie:

Hibernate.initialize(subProcessModel.getElement());

Kiedy jesteś jeszcze w aktywnej sesji.

I jeszcze jedno. Przyjacielska Rada. Masz coś takiego w swojej metodzie:
            for (Model m : modelList)
            if (m.getModelType().getId() == 3) {
                model = m;
                break;
            }

Proszę wstawić ten kod po prostu filtruj te modele o ID typu równym 3 w instrukcji query tylko kilka linijek powyżej.

Trochę więcej czytania:

Konfiguracja fabryczna sesji

Problem z zamkniętą sesją

 63
Author: goroncy,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-02-05 11:01:45

Możesz spróbować ustawić

<property name="hibernate.enable_lazy_load_no_trans">true</property>

W hibernacji.cfg.xml lub persistence.xml

Problem, o którym należy pamiętać z tą właściwością są dobrze wyjaśnione tutaj

 91
Author: Wilianto Indrawan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 12:02:59

Jeśli używasz Springa oznaczyć klasę jako @ Transactional , to Spring zajmie się zarządzaniem sesją.

@Transactional
public class My Class {
    ...
}

Za pomocą @Transactional wiele ważnych aspektów, takich jak propagacja transakcji, jest obsługiwanych automatycznie. W tym przypadku, jeśli zostanie wywołana inna metoda transakcyjna, metoda będzie miała możliwość dołączenia do trwającej transakcji, unikając wyjątku "brak sesji".

 69
Author: user2601995,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-08-28 17:45:37

Najlepszym sposobem radzenia sobie z LazyInitializationException jest użycie dyrektywy JOIN FETCH:

Query query = session.createQuery(
    "from Model m " +
    "join fetch m.modelType " +
    "where modelGroup.id = :modelGroupId"
);

W każdym razie, nie używaj następujących anty-wzorców, jak sugerują niektóre odpowiedzi:

Czasami projekcja DTOjest lepszym Wyborem niż pobieranie Bytów i w ten sposób nie otrzymasz żadnych LazyInitializationException.

 33
Author: Vlad Mihalcea,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-01-04 11:55:32

Otrzymywałem ten sam błąd dla relacji jeden do wielu Dla poniższej adnotacji.

@OneToMany(mappedBy="department", cascade = CascadeType.ALL)

Zmieniony jak poniżej po dodaniu fetch=FetchType.EAGER, zadziałało na mnie.

@OneToMany(mappedBy="department", cascade = CascadeType.ALL, fetch=FetchType.EAGER)
 7
Author: Smruti R Tripathy,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-11-30 18:18:02

Ten wyjątek z powodu wywołania session.getEntityById(), sesja zostanie zamknięta. Musisz więc ponownie dołączyć obiekt do sesji. Lub łatwym rozwiązaniem jest po prostu skonfiguruj {[1] } do swojej entity.hbm.xml lub jeśli używasz adnotacji, po prostu dodaj @Proxy(lazy=false) do swojej klasy encji.

 5
Author: Reddeiah Pidugu,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-09-07 14:37:17

Napotkałem ten sam problem. Myślę, że innym sposobem, aby to naprawić jest to, że można zmienić zapytanie do join fetch twój Element z modelu w następujący sposób:

Query query = session.createQuery("from Model m join fetch m.element where modelGroup.id = :modelGroupId")
 4
Author: Tony Vu,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-04-13 08:44:41

Jeśli używasz spring data jpa, spring boot możesz dodać tę linię w aplikacji.właściwości

spring.jpa.properties.hibernate.enable_lazy_load_no_trans=true
 4
Author: Shaaban Ebrahim,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-06-15 21:24:54

Istnieje kilka dobrych odpowiedzi, które obsługują ten błąd w szerokim zakresie. Natknąłem się na konkretną sytuację Z Spring Security, która miała szybką, choć prawdopodobnie nie optymalną, naprawę.

Podczas autoryzacji użytkownika (bezpośrednio po zalogowaniu i przejściu uwierzytelniania) testowałem jednostkę użytkownika dla określonego organu w niestandardowej klasie, która rozszerza Simpleurlauthenticationsukcesshandler.

My user entity implementuje UserDetails i ma zestaw leniwych załadowanych ról który rzucił " org.hibernacja.LazyInitializationException - could not initialize proxy-no Session" wyjątek. Zmiana tego zestawu z "fetch=FetchType.Leniwe " do " fetch=FetchType.EAGER " naprawił to dla mnie.

 2
Author: Night Owl,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-03-15 01:55:36

Jeśli używasz JPQL, użyj JOIN FETCH jest najprostszym sposobem: http://www.objectdb.com/java/jpa/query/jpql/from#LEFT_OUTER_INNER_JOIN_FETCH_

 1
Author: xihui,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-03-23 21:55:05

Jeśli używasz frameworka Grail's, łatwo jest rozwiązać leniwy wyjątek inicjalizacji używając słowa kluczowego Lazy w określonym polu w klasie Domain.

For-example:

class Book {
    static belongsTo = [author: Author]
    static mapping = {
        author lazy: false
    }
}

Więcej informacji znajdziesz tutaj

 0
Author: Zeb,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-10-27 12:38:04

Oznacza to, że obiekt, do którego próbujesz uzyskać dostęp, nie jest załadowany, więc napisz zapytanie, które spowoduje, że połączy się z obiektem, do którego próbujesz uzyskać dostęp.

Eg:

Jeśli próbujesz pobrać ObjectB z ObjectA, gdzie ObjectB jest kluczem obcym w ObjectA.

Zapytanie:

SELECT objA FROM ObjectA obj JOIN FETCH obj.objectB objB
 0
Author: rex roy,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-04-23 11:36:11

Używa sesji.get(*.class, id); ale nie ładuj funkcji

 -1
Author: Artavazd Manukyan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-08-25 21:21:21

Można również rozwiązać go dodając lazy=false do swojego *.hbm.plik xml lub można init obiektu w Hibernate.init (Object) gdy otrzymujesz obiekt z db

 -3
Author: Sandeep Roniyaar,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-07-31 10:12:07

Wykonaj następujące zmiany w Servlet-context.xml

    <beans:property name="hibernateProperties">
        <beans:props>

            <beans:prop key="hibernate.enable_lazy_load_no_trans">true</beans:prop>

        </beans:props>
    </beans:property>
 -3
Author: ArunDhwaj IIITH,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-04-09 00:29:58