Jak naprawić 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);
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 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);
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, uzyskać 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 ustaw lazyLoad na false, ale nie mogę tego zrobić, dlatego zasugerowano mi kontrolowanie sesji
19 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:
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
2019-06-04 08:45:38
Jeśli używasz Springa oznaczyć klasę jako @ Transactional , to Spring zajmie się zarządzaniem sesją.
@Transactional
public class MyClass {
...
}
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".
Ostrzeżenie Jeśli używasz @Transactional
, pamiętaj o wynikowym zachowaniu. Zobacz też Ten artykuł na typowe pułapki. Na przykład aktualizacje encji są utrzymywane nawet jeśli nie wywołujesz jawnie save
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
2020-03-19 01:04:59
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
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
Najlepszym sposobem obsługi LazyInitializationException
jest użycie JOIN FETCH
dyrektywy:
Query query = session.createQuery("""
select m
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 DTO jest lepszym Wyborem niż pobieranie Bytów, a w ten sposób nie otrzymasz żadnych LazyInitializationException
.
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
2021-01-08 21:07:24
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)
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
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
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
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.
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")
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
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
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
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.
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
Ten sam wyjątek w różnych przypadkach użycia.
Przypadek użycia: spróbuj odczytać dane z DB z projekcją DTO .
Rozwiązanie: użyj metody get zamiast load .
Operacja Generyczna
public class HibernateTemplate {
public static Object loadObject(Class<?> cls, Serializable s) {
Object o = null;
Transaction tx = null;
try {
Session session = HibernateUtil.getSessionFactory().openSession();
tx = session.beginTransaction();
o = session.load(cls, s); /*change load to get*/
tx.commit();
session.close();
} catch (Exception e) {
e.printStackTrace();
}
return o;
}
}
Klasa Trwałości
public class Customer {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "Id")
private int customerId;
@Column(name = "Name")
private String customerName;
@Column(name = "City")
private String city;
//constructors , setters and getters
}
CustomerDAO interface
public interface CustomerDAO
{
public CustomerTO getCustomerById(int cid);
}
Obiekt Transferu Encji Klasa
public class CustomerTO {
private int customerId;
private String customerName;
private String city;
//constructors , setters and getters
}
Klasa Fabryczna
public class DAOFactory {
static CustomerDAO customerDAO;
static {
customerDAO = new HibernateCustomerDAO();
}
public static CustomerDAO getCustomerDAO() {
return customerDAO;
}
}
Entity specific DAO
public class HibernateCustomerDAO implements CustomerDAO {
@Override
public CustomerTO getCustomerById(int cid) {
Customer cust = (Customer) HibernateTemplate.loadObject(Customer.class, cid);
CustomerTO cto = new CustomerTO(cust.getCustomerId(), cust.getCustomerName(), cust.getCity());
return cto;
}
}
Pobieranie danych: Klasa testowa
CustomerDAO cdao = DAOFactory.getCustomerDAO();
CustomerTO c1 = cdao.getCustomerById(2);
System.out.println("CustomerName -> " + c1.getCustomerName() + " ,CustomerCity -> " + c1.getCity());
Obecne Dane
Zapytanie i wyjście generowane przez system Hibernate
Hibernate: wybierz customer0_.Id jako Id1_0_0_, customer0_.Miasto jako City2_0_0_, customer0_.Name jako Nazwa3_0_0_ z CustomerLab31 customer0_ gdzie customer0_.Id=?
CustomerName -> Cody ,CustomerCity - > LA
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
2019-07-14 19:18: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_
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
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
W moim przypadku zagubione session.clear()
powodowało ten problem.
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-10-30 14:04:14
Oznacza to, że używasz JPA lub hibernate w kodzie i wykonujesz modyfikację na DB bez dokonywania transakcji logiki biznesowej. Tak prostym rozwiązaniem jest zaznaczenie fragmentu kodu @ Transactional
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
2020-03-31 04:05:25
Przydarzyło mi się to, gdy korzystałem już z @Transactional(value=...)
i korzystałem z wielu menedżerów transakcji.
Moje formularze wysyłały dane, które już na nich były @JsonIgnore
, więc dane wysyłane z formularzy były niekompletne.
Początkowo używałem rozwiązania anty pattern, ale okazało się, że było niesamowicie powolne. Wyłączyłem to ustawiając na false.
spring.jpa.properties.hibernate.enable_lazy_load_no_trans=false
Poprawka miała na celu zapewnienie, że wszystkie obiekty, które miały leniwie załadowane dane, które nie były ładowane, zostały pobrane z bazy danych najpierw.
Optional<Object> objectDBOpt = objectRepository.findById(object.getId());
if (objectDBOpt.isEmpty()) {
// Throw error
} else {
Object objectFromDB = objectDBOpt.get();
}
Krótko mówiąc, jeśli wypróbowałeś wszystkie inne odpowiedzi, po prostu sprawdź, czy najpierw wczytywasz się z bazy danych, jeśli nie podałeś wszystkich właściwości @JsonIgnore
i używasz ich w zapytaniu bazy danych.
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
2020-11-14 00:37:41
Używa sesji.get(*.class, id); ale nie ładuj funkcji
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
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>
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