No Hibernate Session bound to thread, and configuration does not allow creation of non-transactional one here without using @contoller

StackOverflow https://stackoverflow.com/questions/22111177

  •  18-10-2022
  •  | 
  •  

Question

I'm newbie to spring framework.I have integrated spring + hibernate to create RESTFUI API web service.

public interface IGenericDao {
 long persists(T clazz) throws ResourceFailureException;
 List select(T clazz)throws ResourceFailureException;
}

@Repository(value="genericDao")
public class GenericDao  implements IGenericDao {

 @Autowired
 SessionFactory sessionFactory;

 @Override
 public long persists(T clazz) throws ResourceFailureException {
  long generatedID;
  generatedID = (Long) getCurrentSession().save(clazz);
  getCurrentSession().getTransaction().commit();
  return generatedID;
 }

 @Override
 public List select(T clazz) throws ResourceFailureException {
  String queryStr = " FROM "+clazz.getClass().getName()+" as table WHERE (table.isDelete is null OR"
    + " table.isDelete = false) ";
  return this.select(queryStr);
 }

 protected final Session getCurrentSession() {
        return sessionFactory.getCurrentSession();
    }
}

//Implement GenericDAO class

@Repository(value="roleCapabilityDao")
public class RoleCapabilityDAO extends GenericDao{

 public final void persistRole(final Role role) throws ResourceFailureException {
  persists(role);
 }

 public final List getRoles(final String whereString)
   throws ResourceFailureException {
  String queryStr = "FROM Role " + whereString;
  return select(queryStr);
 }

 public final Role getRoleById(final int roleId) throws ResourceFailureException {
  String whereString = "WHERE id=" + roleId;
  List roles = getRoles(whereString);
  if (roles != null && !roles.isEmpty()) {
   return roles.get(0);
  }
  return null;
 }
}

//Servlet-context class.

@Transactional
public class HibernateUtility {

 private static Logger logger =Logger.getLogger(HibernateUtility.class.getName());

 public HibernateUtility() {


 }

 @Autowired(required=true)
 RoleCapabilityDAO roleCapabilityDao;

 @Autowired(required=true)
 UserDAO userDao;


 public void createDefaultUser(final ServletContext context) {

  SpringBeanAutowiringSupport.processInjectionBasedOnServletContext(this, context);

  Users user = new Users();
  Role role = new Role();
  .....

  try {
   role = roleCapabilityDao.getRoleByName("SystemAdmin");
  }catch (ResourceFailureException re) {
   logger.error("Resource not found" +re.getMessage());
  } 
}

applicationContext.xml

<tx:annotation-driven transaction-manager="transactionManager"/>
<context:annotation-config />
<context:component-scan base-package="com.base" use-default-filters="false"/>

<bean id="propertyConfigurer"
    .....
</bean>

    <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" 
p:driverClassName="${jdbc.driverClassName}"
    p:url="${jdbc.databaseurl}" p:username="${jdbc.username}" p:password="${jdbc.password}">
    <property name="testOnBorrow" value="true"/>
    </bean>

 <bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
    <property name="dataSource" ref="dataSource"></property>
    <property name="configLocation">
        <value>classpath:hibernate.cfg.xml</value>
    </property>
     <property name="configurationClass">
         <value>org.hibernate.cfg.AnnotationConfiguration</value>
     </property>
    <property name="hibernateProperties">
        <props>
            <prop key="hibernate.dialect">${jdbc.dialect}</prop>
            <prop key="hibernate.show_sql">true</prop>
            <prop key="hibernate.hbm2ddl.auto">update</prop>
        </props>
    </property>
  </bean>

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

web.xml

<context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>/WEB-INF/applicationContext.xml</param-value>
</context-param>

<listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>

<listener>
    <listener-class>org.springframework.web.context.request.RequestContextListener</listener-class>
</listener>

<servlet>
    <servlet-name>HibernateUtility</servlet-name>
    <servlet-class>com.base.hibernate.HibernateUtilityServlet</servlet-class>
    <load-on-startup>1</load-on-startup>
</servlet>

//RESTFUL API calls

@Path("/roles")
@Service
@Transactional
public class RoleCapabilityResource {

    public RoleCapabilityResource(){
        super();
    }

    @Autowired
    UserDAO userDao;

    @Autowired
    RoleCapabilityDAO roleCapabilityDao;

    private static Logger roleLogger=Logger.getLogger(RoleCapabilityResource.class.getName());

    @GET
    @Produces(MediaType.APPLICATION_JSON)
    @Path("/getAllRoles")
    @Loggable(value = LogLevel.DEBUG)
    @CapabilityCode(value = "C_User_R")
    public Response getAllRoles(@Context final HttpServletRequest request) {

        HttpSession session = request.getSession();
        try {
        String loggedUser = session.getAttribute("userName").toString();
        Users user = userDao.getCurrentUser(loggedUser.trim());
        if(user == null){
            return Response.status(Response.Status.BAD_REQUEST).type("text/plain").entity("Current User not found").build();
        }
        List<Role> roleList = roleCapabilityDao.getValidRolesForUserRole(user.getRole().getName(), false);
        JSONObject allRolesJson = getRoleJSON(roleList);
        return Response.status(Response.Status.OK).type(MediaType.APPLICATION_JSON).entity(allRolesJson).build();
    } catch (ResourceFailureException re) {
            roleLogger.error("Error in resource"+re.getMessage());
            return Response.status(Response.Status.BAD_REQUEST).type("text/plain").entity(re.toString()).build();
        } 
    }
}

//HibernateUtilizyServlet

import javax.servlet.ServletConfig;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;

import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;


/**
 * Hibernate Utility Servlet is invoked only once during JBoss Startup.
 */
@Service
@Transactional
public class HibernateUtilityServlet extends HttpServlet {



    /**
     * Default serial Version ID.
     */
    private static final long serialVersionUID = 1L;


    @Override
     public void init(ServletConfig config) {
            try {
                super.init(config);
                ServletContext context = getServletContext();
                HibernateUtility hibernateUtil = new HibernateUtility();
                hibernateUtil.createDefaultUser(context);
            } catch (ServletException e) {
                e.printStackTrace();
            }

     }

}

If i run the application it throws below error message

StandardWrapper.Throwable: 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) [:3.1.0.RELEASE]
 at org.hibernate.impl.SessionFactoryImpl.getCurrentSession(SessionFactoryImpl.java:685) [:3.6.0.Final]
 at com.base.dao.GenericDao.getCurrentSession(GenericDao.java:186) [:]
 at com.base.dao.GenericDao.select(GenericDao.java:80) [:]
 at com.base.dao.RoleCapabilityDAO.getRoles(RoleCapabilityDAO.java:29) [:]
 at com.base.dao.RoleCapabilityDAO.getRoleByName(RoleCapabilityDAO.java:40) [:]
 at com.base.hibernate.HibernateUtility.createDefaultUser(HibernateUtility.java:180) [:]
 at com.base.hibernate.HibernateUtilityServlet.init(HibernateUtilityServlet.java:41) [:]

I have tried some links as mentioned below,

1.Spring MVC + Hibernate: No Hibernate Session bound to thread, and configuration does not allow creation of non-transactional one here. 2.I am receiving HibernateException "No Hibernate Session bound to thread, and configuration does not allow creation of non-transactional one here"

but I have not resolved yet.The only difference is here I didn't use @controller annotation.

How to resolve this Error? How to set sessions handle by spring?

No correct solution

OTHER TIPS

HibernateUtilityServlet is no Spring Bean! It is just some simple Http Servlet created by your Servlet container (not by Spring).

Therefore

  • your Spring annotations at HibernateUtilityServlet are ignored (they are only taken in account if your Object is an Spring Bean (created by Spring))
  • you can not inject something in HibernateUtilityServlet

Futuremore: when you create an instance with new (like you did HibernateUtility hibernateUtil = new HibernateUtility();), then this Object will be no Spring Bean. Therefore (you already know it):

  • your Spring annotations at this class are ignored
  • you can not inject something in this object

I don't really know what you want do do with this HibernateUtilityServlet, but it looks like you try to setup the database when the application starts. -- A Much more easyer way would be using the spring default functionality for this:

@Component
public class OnStartupAction implements ApplicationListener<ContextStartedEvent> {

  @Override
  public void onApplicationEvent(final ContextStartedEvent event) {
    // do whatever you need here 
  }
}

More details in this answer of mine.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top