2

I have problem with session in hibernate:

INFO: Starting ProtocolHandler ["http-bio-8080"]
2013-09-10 16:23:11 org.apache.catalina.startup.Catalina start
 INFO: Server startup in 4000 ms
2013-09-10 16:23:13 org.apache.catalina.core.StandardWrapperValve invoke
SEVERE: Servlet.service() for servlet [appServlet] in context with path [/portal] threw          exception [Request processing failed; nested exception is org.hibernate.HibernateException: No Hibernate Session bound to thread, and configuration does not allow creation of non-transactional one here] with root cause
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:687)
    at com.myportal.portal.model.HibernateDao.getSessionFactory(HibernateDao.java:31)
    at com.myportal.portal.model.HibernateDao.testowa(HibernateDao.java:46)
    at com.myportal.portal.controllers.HomeController.home(HomeController.java:35)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)

I've read something about this problem but the solutions don't work in my case.

My Dao class:

package com.myportal.portal.model;
import org.hibernate.classic.Session;
import org.hibernate.SessionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import com.myportal.portal.entity.User;

@Repository
@Transactional(propagation=Propagation.REQUIRED)
public class HibernateDao {
    @Autowired
    private SessionFactory sessionFactory;


    public HibernateDao()
    {

    }
    public HibernateDao(SessionFactory sessionFactory)
    {
        this.sessionFactory = sessionFactory;
    }
    private Session getSessionFactory()
    {
        return sessionFactory.getCurrentSession();
    }

    private void setSessionFactory(SessionFactory sessionFactory)
    {
        this.sessionFactory = sessionFactory;
    }

    public void testowa()
    {
        User u = new User();
        //SessionFactory sf = getSessionFactory();
        //Session s = sf.openSession().beginTransaction()

        // problem with this
        Session session = getSessionFactory();
        //session.save(u);

    }
}

root-context.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:tx="http://www.springframework.org/schema/tx"
    xmlns:context="http://www.springframework.org/schema/context"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
    http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd
    http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">

    <!-- Root Context: defines shared resources visible to all other web components -->


<context:annotation-config/>
<tx:annotation-driven transaction-manager="transactionManager"/>

<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
    <property name="driverClassName" value="com.mysql.jdbc.Driver"/>
    <property name="url" value="jdbc:mysql://localhost/hibernate1"/>
    <property name="username" value="root2"/>
    <property name="password" value=""/>
    <property name="initialSize" value="5"/>
    <property name="maxActive" value="10"/>
</bean>    

<bean id="sessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
   <property name="dataSource" ref="dataSource"/>
   <property name="packagesToScan" value="com.spoleczniak.projekt.model"/>
   <property name="hibernateProperties">
       <props>
           <prop key="dialect">org.hibernate.dialect.MySQLInnoDBDialect</prop>
           <prop key="show_sql">true</prop>
       </props>
   </property>
</bean>

    <bean id="transactionManager"
        class="org.springframework.orm.hibernate3.HibernateTransactionManager">
        <property name="sessionFactory" ref="sessionFactory" />
    </bean>

     <bean class="org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor" />

</beans>

servlet-context.xml

    <!-- DispatcherServlet Context: defines this servlet's request-processing infrastructure -->

    <!-- Enables the Spring MVC @Controller programming model -->
<annotation-driven />
    <context:annotation-config/>
<context:component-scan base-package="com.myportal.portal" />

    <!-- Handles HTTP GET requests for /resources/** by efficiently serving up static resources in the ${webappRoot}/resources directory -->
    <resources mapping="/resources/**" location="/resources/" />

    <!-- Resolves views selected for rendering by @Controllers to .jsp resources in the /WEB-INF/views directory -->
    <beans:bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <beans:property name="prefix" value="/WEB-INF/views/" />
        <beans:property name="suffix" value=".jsp" />
    </beans:bean>

I use it like this:

@Controller
public class RegisterController {

    @Autowired
    private HibernateDao hibernateDao;

    @RequestMapping(value="/register")
    public String registerForm()
    {
        hibernateDao.testowa();
        return "register";
    }
}

How can I fix it?

I change DAO and create UserService, but error still appears :

DAO:

@Repository
public class HibernateDao {
    @Autowired
    private SessionFactory sessionFactory;


    public HibernateDao()
    {

    }
    public HibernateDao(SessionFactory sessionFactory)
    {
        this.sessionFactory = sessionFactory;
    }
    private Session getSessionFactory()
    {
        return sessionFactory.getCurrentSession();
    }

    private void setSessionFactory(SessionFactory sessionFactory)
    {
        this.sessionFactory = sessionFactory;
    }

    public void testowa()
    {
        User u = new User();
        //SessionFactory sf = getSessionFactory();
        //Session s = sf.openSession().beginTransaction()

        // problem with this
        Session session = getSessionFactory();
        //session.save(u);

    }
} 

UserService:

@Service
public class UserService {

    @Autowired
    private HibernateDao hibernateDao;


    @Transactional
    public void addContact() 
    {
        hibernateDao.testowa(); 
    }
}

Controller:

@Controller
public class RegisterController {

    @Autowired
    private UserService userService;

    @RequestMapping(value="/register")
    public String registerForm()
    {
        userService.addContact();
        return "register";
    }
}
2
  • 1
    It looks you posted the same content for servlet-context.xml as you did for root-context.xml. That was a mistake, correct? Commented Sep 16, 2013 at 13:50
  • Sorry, I made mistake in this post.I corrected post. Commented Sep 16, 2013 at 14:16

3 Answers 3

7

What's happening is your servlet-context.xml is overwriting beans in your root-context.xml because it's declaring a component-scan for the package containing the @Repository class. In servlet-context.xml, you have

<context:component-scan base-package="com.myportal.portal" />

while your HibernateDao class is in com.myportal.portal.model. This ApplicationContext will create a HibernateDao bean without transaction management, since it doesnt have <tx:annotation-driven>. The HibernateDao bean that is autowired in your @Controller is this one, not the one from the root-context.xml (which has transaction management).

To fix this, you will want to start by adding

<context:component-scan base-package="com.myportal.portal.model" />

to your root-context.xml and removing <context:annotation-config/> (it is redundant). You then want to modify the component-scan in the servlet-context.xml to something more specific that doesn't contain the package of the @Repository classes

<context:component-scan base-package="com.myportal.portal.controllers" />

that package would contain your @Controller classes. You also don't need the <context:annotation-config>.

Sign up to request clarification or add additional context in comments.

3 Comments

Ok, I changed it.Now I have problem with creating been: Error creating bean with name 'hibernateDao' defined in file [I:\Spring\vfabric-tc-server-developer-2.8.1.RELEASE\base-instance\wtpwebapps\portalSpol\WEB-INF\classes\com\myportal\portal\model\HibernateDao.class]: Initialization of bean failed; nested exception is java.lang.NoClassDefFoundError: org/objectweb/asm/util/TraceClassVisitor
I added asm and cglib dependency and this error disappeared. Now I have:No mapping found for HTTP request with URI [/portal/] in DispatcherServlet with name 'appServlet'. So I think that <context:component-scan base-package="com.myportal.portal.controllers" /> doesn't see my controllers (controllers are in this package). before modification it worked fine.
ok, now it works fine. Thanks for your help, your advices are helpful for me.
0
No Hibernate Session bound to thread, and configuration does not allow creation of non-transactional one here

This means that there is no current transaction within that thread.

As you corrected me the class is annotated with @Transactional but I see that it does not implement an interface. It may happen that the generated proxy does not expose the annotation as happens when you annotate a controller without it implementing an interface.

See why CGLIB proxies do not retain certain annotations.

4 Comments

Oh right, did not read the code fully. But I now checked that the DAO object is not implementing an interface. Maybe the proxy generated does not expose the annotation in runtime.
The initialization step would have complained if CGLIB was missing from classpath.
It's not like CGLIB is not there, but that CGLIB creates subclasses to make proxies and subclasses do not retain annotations if you did not annotated the annotation with @Inherited
The proxy doesn't need to have the annotation, it's built because of the annotation. The proxy just has the functionality.
0

During beans instantiation servlet-context.xml is read and beans with @Controller, @Service, @Repository are instantiated.

Now when application-context.xml (which has <tx:annotation-driven />) is read the beans are already there and so doesn't get transactional behavior. Make the package in servlet-context.xml specific to UI like controller/ Or exclude the Service, Repository package from component-scan.

<context:component-scan base-package="com.java.controllers"/> 

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.