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
  •  | 
  •  

문제

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?

올바른 솔루션이 없습니다

다른 팁

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.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top