Announcement Announcement Module
Collapse
No announcement yet.
No Hibernate Session bound to thread... Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • No Hibernate Session bound to thread...

    Hello all,

    I have changed my web application to spring framework and have now following problem on connecting hibernate... Maybe you can look at my configurations and tell me what I am doing wrong...

    Exception:
    Code:
    org.hibernate.HibernateException: No Hibernate Session bound to thread, and configuration does not allow creation of non-transactional one here
    	at org.springframework.orm.hibernate3.SpringSessionContext.currentSession(SpringSessionContext.java:63)
    	at org.hibernate.impl.SessionFactoryImpl.getCurrentSession(SessionFactoryImpl.java:574)
    	at de.myapp.persistenz.impl.BasicDAOImpl.getCurrentSession(BasicDAOImpl.java:35)
    	at de.myapp.persistenz.impl.BasicDAOImpl.findByCriteria(BasicDAOImpl.java:97)
    	at de.myapp.persistenz.impl.MailTriggerDAO.findByJobname(MailTriggerDAO.java:30)
    	...
    Now my configurations...

    applicationContext.xml
    Code:
    <?xml version="1.0" encoding="UTF-8"?>
    
    <beans xmlns="/schema/beans"
    	xmlns:xsi="/2001/XMLSchema-instance"
    	xmlns:tx="/schema/tx"
    	xsi:schemaLocation="
    /schema/beans 
    /schema/beans/spring-beans-2.0.xsd
    /schema/tx 
    /schema/tx/spring-tx-2.0.xsd">
    
    	<!--  Transaction handling -->
    	<tx:annotation-driven transaction-manager="txManager"/>
    
    	<bean id="datasource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
    	   <property name="driverClass" value="com.mysql.jdbc.Driver" />
    	   <property name="jdbcUrl" value="..." />
    	   <property name="user" value="ww" />
    	   <property name="password" value="" />
    	   <property name="minPoolSize" value="2" />
    	   <property name="maxPoolSize" value="4" />
    	</bean>
    
    	<bean id="hibernateSessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
    		<property name="dataSource" ref="datasource" />
    		<property name="annotatedClasses">
    			<list>
    				...
    				<value>de.myapp.persistenz.interf.MailTriggerBO</value>
    				...
    			</list>
    		</property>
    		<property name="hibernateProperties">
    				<props>
    					<prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>
    					<prop key="hibernate.cache.provider_class">org.hibernate.cache.EhCacheProvider</prop>
    					<prop key="hibernate.hbm2ddl.auto">update</prop>
    				</props>
    		</property>
    		
    	</bean>
    
    	<!-- ### Service-Beans ### -->
    	...
    	<bean id="mailTriggerService" class="de.myapp.persistenz.service.MailTriggerServiceImpl">
    		<property name="mailTriggerDAO" ref="mailTriggerDAO" />
    	</bean>
    	...
    
    	<!-- ### Entitiy DAOs ### -->
    	...
    	<bean id="mailTriggerDAO" class="de.myapp.persistenz.impl.MailTriggerDAO">
    		<constructor-arg ref="hibernateSessionFactory" />
    	</bean>
    	...
    
    
    	<!-- ### References to services ### -->
    	...
    	<bean id="schedulerCentral" class="de.myapp.anwendungskern.scheduler.impl.SchedulerCentralImpl">
    		<property name="mailTriggerService" ref="mailTriggerService" />
    	</bean>
    
    	<bean id="wobScheduler" class="de.myapp.anwendungskern.WOBScheduler">
    		<property name="schedulerCentral" ref="schedulerCentral" />
    	</bean>
    	
    	<bean id="txManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager" >
    		<property name="sessionFactory" ref="hibernateSessionFactory"/>
    	</bean>
    </beans>
    The initially started Servlet "WOBScheduler" (the init() calls a startup method for starting a scheduler):
    Code:
    public class WOBScheduler extends HttpServlet {
        
    	private static final long serialVersionUID = -6163092977736246215L;
    	protected static final Log logger = LogFactory.getLog(WOBScheduler.class);
    	private SchedulerCentral schedulerCentral;
    	
        public WOBScheduler() {
            super();
        }
    
        public void init() throws ServletException {
        	TraceHelper.entry(logger, this, "init");
    
        	ApplicationContext context = WebApplicationContextUtils.getRequiredWebApplicationContext(this.getServletContext());
        	
    	AutowireCapableBeanFactory factory = context.getAutowireCapableBeanFactory();		
    	factory.autowireBeanProperties(this, AutowireCapableBeanFactory.AUTOWIRE_BY_TYPE, true);		
    
    	Assert.isNotNull(schedulerCentral, "schedulerCentral != null");
        	
        	super.init();
        	ServletContext ctx = getServletContext();	
        	schedulerCentral.startUp((StdSchedulerFactory) ctx.getAttribute(QIL.QUARTZ_FACTORY_KEY));
        	
        	TraceHelper.exit(logger, this, "init");
        }
    
    	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    	}
    
    	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    	}
    	
        /**
         * Spring injection.
    	 */
    	public void setSchedulerCentral(SchedulerCentral schedulerCentral) {
    		this.schedulerCentral = schedulerCentral;
    	}
    
    }
    A part of "SchedulerCentralImpl" which is calling the mailTriggerService (which is being injected):
    Code:
    public class SchedulerCentralImpl implements SchedulerCentral {
    	...
    	private MailTriggerService mailTriggerService;
    	...
    	public final void startUp(final StdSchedulerFactory factory) {
    		...
    		MailTriggerBO mtBO = mailTriggerService.findByJobname(MAILJOB);
    		...
    	}
    
    	public void setMailTriggerService(MailTriggerService mailTriggerService) {
    		this.mailTriggerService = mailTriggerService;
    	}
    }
    Now I show you the MailTriggerService:
    Code:
    public class MailTriggerServiceImpl implements MailTriggerService {
    	private MailTriggerDAO mailTriggerDAO;
    
    // sorry, can not write an at-sign here.... - it's an annotation :)
    	\at Transactional(propagation=Propagation.REQUIRED)
    	public void createNewMailTrigger(MailTriggerBO mailTrigger) {
    		Assert.isNotNull(mailTriggerDAO, "mailTriggerDAO != null");
    		mailTriggerDAO.save(mailTrigger);
    	}
    
    	\at Transactional(propagation=Propagation.REQUIRED, readOnly=true)
    	public List<MailTriggerBO> findAll() {
    		Assert.isNotNull(mailTriggerDAO, "mailTriggerDAO != null");
    		List<MailTriggerBO> list = mailTriggerDAO.findAll();
    		return list;
    	}
    
    	\at Transactional(propagation=Propagation.REQUIRED, readOnly=true)
    	public MailTriggerBO findByJobname(String jobname) {
    		Assert.isNotNull(mailTriggerDAO, "mailTriggerDAO != null");
    		MailTriggerBO mailTrigger = mailTriggerDAO.findByJobname(jobname);
    		return mailTrigger;
    	}
    	...
    }

    And at last the used DAO and its ancestor MailTriggerDAO:
    Code:
    public class MailTriggerDAO extends BasicDAOImpl<MailTriggerBO, Long> {
    	public MailTriggerDAO(SessionFactory factory) {
    		super(factory, MailTriggerBO.class);
    	}
    	
    	public MailTriggerBO findByJobname(final String job) {
    		List<MailTriggerBO> jobList = findByCriteria(Restrictions.eq("job", job));
    		if (jobList.size() == 0) {
    			return null;
    		} else {
    			return jobList.get(0);
    		}
    	}
    }
    BasicDAOImpl:
    Code:
    public class BasicDAOImpl<T, ID extends Serializable> implements BasicDAO<T, ID>  {
    	protected SessionFactory factory;
    	Class clazz;
    	public BasicDAOImpl(SessionFactory factory, Class<T> clazz) {
    		this.factory = factory;
    		this.clazz = clazz;
    	}
    
    	protected Session getCurrentSession() {
    		return factory.getCurrentSession();
    	}
    
    	public T findById(final ID id) {
    		return (T) getCurrentSession().get(clazz, id);
    	}
    
    	public void reattach(T object) {
    		getCurrentSession().lock(object, LockMode.NONE);
    	}
    
    	public void save(T object) {
    		getCurrentSession().saveOrUpdate(object);
    	}
    
    	public void update(T object) {
    		getCurrentSession().update(object);
    	}
    
    	public T merge(T object) {
    		return (T) getCurrentSession().merge(object);
    	}
    
    	public void saveOrUpdate(T object) {
    		getCurrentSession().saveOrUpdate(object);
    	}
    
    	public void delete(T object) {
    		getCurrentSession().delete(object);
    	}
    
    	public List<T> findAll() {
    		return (List<T>) getCurrentSession().createCriteria(clazz).list();
    	}
    
    	public List<T> findByCriteria(Criterion... criterion) {
    		Criteria criteria = getCurrentSession().createCriteria(clazz);
    		for (Criterion c : criterion) {
    			criteria.add(c);
    		}
    		return criteria.list();
    	}
    }
    Can you see the problem?

    Thank you in advance!

  • #2
    Hey, I didn't find trasactions any where in your code. You can use either Programatic or Declarative trasctions.

    getCurrentSession will get the session binded with the transaction. If you don't start the trasaction then there is no session available for you.

    Comment


    • #3
      Post the full stacktrace...

      Also do you really need the servlet? You seem to be using quartz so why not simply configure quartz with spring and use it that way...

      Comment


      • #4
        Originally posted by sirikar View Post
        Hey, I didn't find trasactions any where in your code. You can use either Programatic or Declarative trasctions.

        getCurrentSession will get the session binded with the transaction. If you don't start the trasaction then there is no session available for you.
        I am using annotation driven transaction-manager. I couldn't write any "@"-signs in my first post on this board, because it said to me, I may not enter URLs ... that's why I escaped the at-chars with an backslash.


        I have now the following solution, I simply replaced the BasicDAOImpl by the following one, which uses HibernateTemplates...

        But I still don't know what was wrong with the other method.

        Code:
        public class BasicDAOImpl<T, ID extends Serializable> implements BasicDAO<T, ID>  {
        
        	public static final Log logger = LogFactory.getLog(BasicDAOImpl.class);
        
        //	protected SessionFactory factory;
        	protected HibernateTemplate template;
        
        	private Class clazz;
        
        	public BasicDAOImpl(SessionFactory factory, Class<T> clazz) {
        		this.template = new HibernateTemplate(factory);
        		this.clazz = clazz;
        	}
        
        	@SuppressWarnings("unchecked")
        	public T findById(final ID id) {
        		return (T) template.execute(new HibernateCallback() {
        			public Object doInHibernate(Session session)
        					throws HibernateException, SQLException {
        				return session.get(clazz, id);
        			}
        		});
        
        	}
        
        	/**
             * reattaches a object from an older session to the current session. Uses
             * LockMode.Read to verifiy if the object does exist.
             * 
             * @param object
             */
        	public void reattach(T object) {
        		template.lock(object, LockMode.NONE);
        	}
        
        	public void save(T object) {
        		template.saveOrUpdate(object);
        	}
        
        	public void update(T object) {
        		template.update(object);
        	}
        
        	public T merge(T object) {
        		return (T) template.merge(object);
        	}
        
        	public void saveOrUpdate(T object) {
        		template.saveOrUpdate(object);
        	}
        
        	public void delete(final T object) {
        		template.delete(object);
        	}
        
        	@SuppressWarnings("unchecked")
        	public List<T> findAll() {
        		return (List<T>) template.execute(new HibernateCallback() {
        			public Object doInHibernate(Session session)
        					throws HibernateException, SQLException {
        				return session.createCriteria(clazz).list();
        			}
        		});
        	}
        
        	@SuppressWarnings("unchecked")
        	public List<T> findByCriteria(final Criterion... criterion) {
        		return (List<T>) template.execute(new HibernateCallback() {
        			public Object doInHibernate(Session session)
        					throws HibernateException, SQLException {
        				Criteria criteria = session.createCriteria(clazz);
        				for (Criterion c : criterion)
        					criteria.add(c);
        				return criteria.list();
        			}
        		});
        	}
        
        }
        Originally posted by Marten Deinum View Post
        Post the full stacktrace...

        Also do you really need the servlet? You seem to be using quartz so why not simply configure quartz with spring and use it that way...
        As I said, I am rewriting an old application which originally didn't use spring... so the quertz part will follow soon :-)
        Last edited by untitled1; Feb 6th, 2009, 09:03 AM.

        Comment

        Working...
        X