Announcement Announcement Module
Collapse
No announcement yet.
LazyLoading caused session error | How to open session? Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • LazyLoading caused session error | How to open session?

    Hi!

    All my DAOImplementations are @Repository's and extend the help class DAOSupport:
    Code:
    @Transactional
    public abstract class DAOSupport {
    
    	@Autowired
    	protected HibernateTransactionManager	_manager;
    
    	//
    	// RIGHT WAY?
    	// openSession() ??? some one have to close the opened....
    	//
    	private Session getSession() {
    		Session session = _manager.getSessionFactory().getCurrentSession(); // <-- 
    		return session;
    	}
    
    	protected void defaultUpdate(Object object) {
    		getSession().update(object);
    	}
    
    	protected Serializable defaultSave(Object object) {
    		return getSession().save(object);
    	}
    
    	protected void defaultDelete(Object object) {
    		getSession().delete(object);
    	}
    	protected <T> T defaultGetByID(Class<T> clazz, Serializable id) {
    		return (T) getSession().get(clazz, id);
    	}
    
    	protected <T> List<T> defaultGetList(Class<T> clazz, Criterion... criterions) {
    		Session session = getSession();
    		Criteria criteria = session.createCriteria(clazz);
    		
    		if (criterions != null) {
    			for (Criterion c : criterions) {
    				criteria.add(c);
    			}
    		}
    
    		return criteria.list();
    	}
    
    	@SuppressWarnings("unchecked")
    	protected <T> T defaultGetUniqueResult(Class<T> clazz, Criterion... criterions) {
    		Session session = getSession();
    		Criteria criteria = session.createCriteria(clazz);
    		
    		if (criterions != null) {
    			for (Criterion c : criterions) {
    				criteria.add(c);
    			}
    		}
    		return (T) criteria.uniqueResult();
    	}
    
    }
    I suppose this is not the right way to open/start a Session.

    If I use getCurrentSession(), i get an exception (in different @Service's):
    org.hibernate.LazyInitializationException: could not initialize proxy - no Session
    If I use openSession(), i get exception:
    org.hibernate.HibernateException: Illegal attempt to associate a collection with two open sessions
    My Configuration:

    Code:
    @Configuration
    @EnableWebMvc
    @EnableTransactionManagement
    @ComponentScan(basePackages="myproject.blabla.*")
    public class AppConfiguration extends WebMvcConfigurerAdapter {
    
    	@Bean
    	public InternalResourceViewResolver getInternalResourceViewResolver() {
    
    		InternalResourceViewResolver resolver = new InternalResourceViewResolver();
    		resolver.setPrefix("/WEB-INF/views/");
    		resolver.setSuffix(".jsp");
    
    		return resolver;
    	}
    	@Bean
    	public DataSource myDataSource() {
    
    		DriverManagerDataSource dataSource = new DriverManagerDataSource();
    		dataSource.setDriverClassName(Driver.class.getName());
    		dataSource.setUrl("jdbc:mysql://localhost/myproject");
    		dataSource.setUsername("root");
    		dataSource.setPassword("");
    
    		return dataSource;
    	}
    	
    	@Bean
    	public AnnotationSessionFactoryBean sessionFactory() {
    		
    		Properties props = new Properties();
    		props.put("hibernate.dialect", CustomMysqlDialect.class.getName());
    		props.put("hibernate.format_sql", "true");
    		props.put("hibernate.connection.charSet", "UTF-8");
    		props.put("hibernate.connection.useUnicode", "true");
    		props.put("hibernate.show_sql", "false");
    		props.put("hibernate.connection.characterEncoding", "UTF-8");
    
    		AnnotationSessionFactoryBean sessionFactory = new AnnotationSessionFactoryBean();
    		
    		sessionFactory.setPackagesToScan(new String[] { "myproject.blabla.db.*" });
    		sessionFactory.setHibernateProperties(props);
    		sessionFactory.setDataSource(myDataSource());
    		sessionFactory.setSchemaUpdate(true);
    
    		return sessionFactory;
    	}
    	
    	@Bean
    	public HibernateTransactionManager transactionManager() {
    		return new HibernateTransactionManager(sessionFactory().getObject());
    	}
    
    	@Bean
    	public ReloadableResourceBundleMessageSource messageSource() {
    		ReloadableResourceBundleMessageSource msrc = new ReloadableResourceBundleMessageSource();
    		msrc.setBasename("/WEB-INF/lang/lang");
    		msrc.setCacheSeconds(0);// TODO
    		return msrc;
    	}
    
    	
    	@Override
    	public void addInterceptors(InterceptorRegistry registry) {
    		OpenSessionInViewInterceptor interceptor = new OpenSessionInViewInterceptor();
    		interceptor.setSessionFactory(transactionManager().getSessionFactory());
    		registry.addWebRequestInterceptor(interceptor);
    	}
    	
    	@Override
    	public void addResourceHandlers(ResourceHandlerRegistry registry) {
    		registry.addResourceHandler("/resources/**").addResourceLocations("/resources/");
    	}
    }
    Would you give me some helpful advices?

    Thanks

  • #2
    Your cod eis wrong... using the TransactionManager to get access to the sessionfactory is just wrong. You should simply inject the SessionFactory. Your getCurrentSession approach is correct you shouldn't use openSession as that opens a new hibernate session outside the scope spring which in the end leaves your application unresponsive as your databse connection are all used.

    Another note your hibernate.connection properties are useless as you are injecting a datasource.

    Regarding transactions, your @Service should be the transactional boundary/layer NOT your dao so I suggest you move your transaction annotations.

    Comment


    • #3
      thank you very much.

      After SessionFactory injection i got "org.hibernate.LazyInitializationException: could not initialize proxy - no Session".

      We give up. Our "spring for web" experimental phase is through. Spring is overloaded and very hard to maintenance. Documentation is sometimes depricated and not simple to read. Every new Version requires new tutorial. AnnotationConfiguration is ON but not fully supported. For professional and highperformance webapplications is Spring MVC + hibernate just unsuitable.
      Very sad. I hope we will try it later, when spring get stable. I like the idea of web mvc.

      Comment


      • #4
        Using (and have used) spring in a lot of high performance applications without problems also the reference guide is often mentioned is one of the best around (compared to other open source projects).

        The error you get is in general due to a wrong transaction setup or duplicate component-scanning.

        Comment

        Working...
        X