Java 没有绑定到线程的Hibernate会话,并且配置不允许在不使用@contoller的情况下在此处创建非事务会话

Java 没有绑定到线程的Hibernate会话,并且配置不允许在不使用@contoller的情况下在此处创建非事务会话,java,spring,hibernate,Java,Spring,Hibernate,我是spring框架的新手。我集成了spring+hibernate来创建RESTFUIAPI web服务 public interface IGenericDao { long persists(T clazz) throws ResourceFailureException; List select(T clazz)throws ResourceFailureException; } @Repository(value="genericDao") public class Generi

我是spring框架的新手。我集成了spring+hibernate来创建RESTFUIAPI web服务

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();
    }
}
//实现GenericDAO类

@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上下文类

@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>
如果我运行应用程序,它会抛出下面的错误消息

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) [:]
我尝试了下面提到的一些链接

一,。。 二,

但我还没有解决。唯一的区别是我没有使用@controller注释

如何解决此错误?
如何通过spring设置会话句柄?

HibernateUtilityServlet不是Springbean!它只是由Servlet容器(而不是Spring)创建的一些简单的httpservlet

所以

  • 忽略
    HibernateUtilityServlet
    上的Spring注释(只有当对象是Springbean(由Spring创建)时才会考虑它们)
  • 您不能在
    HibernateUtilityServlet
Futuremore:当您使用
new
创建实例时(就像您所做的
hibernateUtil=new HibernateUtility();
),那么这个对象将不是SpringBean。因此 (你已经知道了):

  • 该类中的Spring注释将被忽略
  • 您不能在此对象中注入内容

我真的不知道您想用这个
HibernateUtilityServlet
做什么,但看起来您好像在应用程序启动时尝试设置数据库。--更简单的方法是使用spring的默认功能:

@Component
public class OnStartupAction implements ApplicationListener<ContextStartedEvent> {

  @Override
  public void onApplicationEvent(final ContextStartedEvent event) {
    // do whatever you need here 
  }
}
@组件
公共类OnStartupAction实现ApplicationListener{
@凌驾
ApplicationEvent上的公共无效(最终ContextStartedEvent事件){
//你需要什么就做什么
}
}

更多详细信息,请参见我的。

@Transactional应该位于存储库或服务级别classyes。我们在服务级别类中使用了HibernateUtibility,它由加载时的servlet上下文类调用。由于异常是从类“HibernateUtibility”引发的,所以我们在那里尝试了@Transactional注释,但对我们没有帮助。从服务级别类中,我们没有遇到异常。在服务类中创建一个服务类autowire DAO,并使用服务类进行访问。您是否可以发布
HibernateUtilityServlet
的代码,因为它涉及到该类。@Ralph我已经添加了HibernateUtilityServlet类。
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();
            }

     }

}
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) [:]
@Component
public class OnStartupAction implements ApplicationListener<ContextStartedEvent> {

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