I have searched all StackOverflow site and Google, and 99.9% of questions are about web application, but I've not found any solution for a Java standalone application (runs in Linux terminal "java -jar myApp.jar") for the classic exception "org.hibernate.LazyInitializationException: could not initialize proxy - no Session"
My project is using Spring 4.0.7 + Hibernate 4.3.6.Final + Log4J 1.2.17 + BoneCP 0.8.0
I have tried the following solutions:
- @Service and @Transactional annotation in Client class, and in the classes that Client class calls;
- @Service and @Transactional(propagation = Propagation.REQUIRED) annotation in Client class, and in the classes that Client class;
- Switched from @Service to @Component and retried items 1 and 2 above;
- Tried using TransactionTemplate and executing client.start() method inside the TransactionCallback.doInTransaction() method;
- I have tried removing @Service and @Transactional from Client class and removing from classes called by Client class.
I've tried all this and I am still getting org.hibernate.LazyInitializationException: could not initialize proxy - no Session
The comments in code is what I have tried too.
Important note: The project uses a Facade class, that contains all methods used by application.
Spring configuration is loaded by the following XML:
<beans>
<context:annotation-config />
<context:component-scan base-package="com.mycompany" />
<context:property-placeholder location="classpath:persistence.properties" />
<tx:annotation-driven transaction-manager="transactionManager" />
<!-- BoneCP -->
<bean id="dataSource" class="com.jolbox.bonecp.BoneCPDataSource" destroy-method="close">
<property name="driverClass" value="${jdbc.driverClassName}"/>
<property name="jdbcUrl" value="${jdbc.url}"/>
<property name="username" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
<property name="idleConnectionTestPeriodInMinutes" value="60"/>
<property name="idleMaxAgeInMinutes" value="240"/>
<property name="maxConnectionsPerPartition" value="30"/>
<property name="minConnectionsPerPartition" value="10"/>
<property name="partitionCount" value="3"/>
<property name="acquireIncrement" value="5"/>
<property name="statementsCacheSize" value="100"/>
<property name="releaseHelperThreads" value="3"/>
</bean>
<bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="packagesToScan" value="com.mycompany.domain.entity" />
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">${hibernate.dialect}</prop>
<prop key="hibernate.default_schema">${hibernate.default_schema}</prop>
<prop key="hibernate.show_sql">${hibernate.show_sql}</prop>
<prop key="hibernate.cache.use_second_level_cache">${hibernate.cache.use_second_level_cache}</prop>
<prop key="hibernate.cache.use_query_cache">${hibernate.cache.use_query_cache}</prop>
<prop key="hibernate.cache.region.factory_class">${hibernate.cache.region.factory_class}</prop>
<!-- I have tried setting "current_session_context_class", but still getting "org.hibernate.LazyInitializationException: could not initialize proxy - no Session" -->
<!-- <prop key="hibernate.current_session_context_class">org.springframework.orm.hibernate4.SpringSessionContext</prop> -->
</props>
</property>
</bean>
<bean id="transactionManager" class="org.springframework.orm.hibernate4.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory" />
<property name="dataSource" ref="dataSource" />
</bean>
<bean id="transactionTemplate" class="org.springframework.transaction.support.TransactionTemplate">
<property name="transactionManager" ref="transactionManager"/>
</bean>
<bean id="persistenceExceptionTranslationPostProcessor" class="org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor"/>
<bean id="client" class="com.mycompany.console.Client" />
</beans>
Project main class:
package com.mycompany.console;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
@Service
@Transactional(propagation = Propagation.REQUIRED)
public class Client {
private static final Logger logger = Logger.getLogger(Client.class);
public static void main(String args[]) {
ApplicationContext applicationContext = null;
// Load Spring application context
try {
applicationContext = new ClassPathXmlApplicationContext("springHibernateConfig.xml");
final Client client = applicationContext.getBean("client"); // Or applicationContext.getBean(Client.class)
// Already tried using TransactionTemplate, but still getting "org.hibernate.LazyInitializationException: could not initialize proxy - no Session"
// TransactionTemplate transactionTemplate = (TransactionTemplate) applicationContext.getBean("transactionTemplate");
// transactionTemplate.execute(new TransactionCallback() {
// @Override
// public Object doInTransaction(TransactionStatus status) {
// client.start(args);
// return null;
// }
// });
client.start(args);
} catch (Exception e) {
System.err.println("Error loading Spring application context: " + e.getMessage());
e.printStackTrace();
System.exit(1);
}
}
private void start(String args[]) {
// List, Save, Update, Delete entities
//
// Calls Facade.instance().getUserById(1L), for example
//
// [...]
}
}
Facade class (ABDomain):
package com.mycompany.domain.facade;
@Service
@Transactional(propagation = Propagation.REQUIRED)
public class ABDomain {
public static ABDomain instance() {
// SpringUtil implements ApplicationContextAware
return SpringUtil.getApplicationContext().getBean(ABDomain.class);
}
public User getUserById(Long id) {
/*
UsuarioDao is an interface, and its
implementation UsuarioDaoImpl extends AbstractHibernateDao
*/
return Registry.getUserDao().findById(id);
}
}
Registry class:
package com.mycompany.domain.registry;
@Component
@Transactional
public class Registry {
private static ApplicationContext applicationContext;
@Autowired(required = true)
public Registry(ApplicationContext appContext) {
applicationContext = appContext;
}
public static UserDao getUserDao() {
return applicationContext.getBean(UserDao.class);
}
}
EDIT:
Adding stack trace for better understanding.
Note:
- ABDomain is the application Facade (mentioned above).
- Inbox is another class that is called by Client class
org.springframework.orm.hibernate4.HibernateSystemException: could not initialize proxy - no Session; nested exception is org.hibernate.LazyInitializationException: could
not initialize proxy - no Session
at org.springframework.orm.hibernate4.SessionFactoryUtils.convertHibernateAccessException(SessionFactoryUtils.java:216)
at org.springframework.orm.hibernate4.HibernateExceptionTranslator.convertHibernateAccessException(HibernateExceptionTranslator.java:57)
at org.springframework.orm.hibernate4.HibernateExceptionTranslator.translateExceptionIfPossible(HibernateExceptionTranslator.java:44)
at org.springframework.dao.support.ChainedPersistenceExceptionTranslator.translateExceptionIfPossible(ChainedPersistenceExceptionTranslator.java:59)
at org.springframework.dao.support.DataAccessUtils.translateIfNecessary(DataAccessUtils.java:213)
at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:147)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:207)
at com.sun.proxy.$Proxy120.findLastPosition(Unknown Source)
at com.mycompany.domain.facade.ABDomain.findLastPosition(ABDomain.java:832)
at com.mycompany.domain.facade.ABDomain$$FastClassBySpringCGLIB$$f56e1d49.invoke()
at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:204)
at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:708)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157)
at org.springframework.transaction.interceptor.TransactionInterceptor$1.proceedWithInvocation(TransactionInterceptor.java:98)
at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:262)
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:95)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:644)
at com.mycompany.domain.facade.ABDomain$$EnhancerBySpringCGLIB$$4c071cee.findLastPosition()
at com.mycompany.cpr.client.Inbox.updateLastPosition(Inbox.java:714)
at com.mycompany.cpr.client.Inbox.processMessage(Inbox.java:604)
at com.mycompany.cpr.client.Inbox$3.run(Inbox.java:934)
at java.lang.Thread.run(Thread.java:745)
Caused by: org.hibernate.LazyInitializationException: could not initialize proxy - no Session
at org.hibernate.proxy.AbstractLazyInitializer.initialize(AbstractLazyInitializer.java:165)
at org.hibernate.proxy.AbstractLazyInitializer.getImplementation(AbstractLazyInitializer.java:286)
at org.hibernate.proxy.pojo.javassist.JavassistLazyInitializer.invoke(JavassistLazyInitializer.java:185)
at com.mycompany.domain.entity.Vehicle_$$_jvst374_1e.getId(Vehicle_$$_jvst374_1e.java)
at com.mycompany.domain.dao.impl.LastPositionDaoImpl.findLastPosition(LastPositionDaoImpl.java:34)
at sun.reflect.GeneratedMethodAccessor1487.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:483)
at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:317)
at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:190)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157)
at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:136)
EDIT 2:
Inbox is a class that is called by Client class (the main class). Inbox has no annotation, but I already tried @Service @Transactional or @Component @Transactional annotations. I'm looking for a solution like OpenSessionInViewFilter commonly used in web projects.
@Serviceand@Transactional(propagation = Propagation.REQUIRED)annotations. But it isn't working with and without those annotations. - shimataivehicle.getOwner()) in another class (Inbox class, that has no annotation, but I already tried @Service @Transactional and @Component @Transactional annotations). The problem is when Spring + Hibernate creates a proxy and then I try to access @ManyToOne fields, I get that errororg.hibernate.LazyInitializationException: could not initialize proxy - no Session. I'm looking for a solution like OpenSessionInViewFilter commonly used in web projects. - shimatairefreshmethod to synchronize the object to the level 1 cache. - Luiggi Mendoza