先看代码:
package connFlex.impl;import java.util.List;import org.hibernate.Hibernate;
import org.hibernate.SQLQuery;
import org.hibernate.Session;
import org.springframework.orm.hibernate3.HibernateCallback;
import org.springframework.orm.hibernate3.support.HibernateDaoSupport;import connFlex.QuerySuperManagerDao;
import pojo.SuperManager;public class QuerySuperManager extends HibernateDaoSupport implements QuerySuperManagerDao  { ///验证登陆
public List FindSuperManager(final String username) throws Exception{
//System.out.println("xxxxx");
List<SuperManager> list=null;

System.out.println(getHibernateTemplate());
//如果要进行增删改的动作,那么要开启事务
return (List)getHibernateTemplate().execute(new HibernateCallback(){
public Object doInHibernate(Session session){
SQLQuery q = session.createSQLQuery("select {sm.*} from supermanager sm where sm.userName='"+username+"'");
q.addEntity("sm", SuperManager.class);
List list1=q.list();
return list1;
}
});

// SuperManager[] superManager = new SuperManager[list.size()];
//         for(int i=0;i<list.size();i++){
//          superManager[i] = (SuperManager)list.get(i);
//         }  
}
public List FindSumSuperManager() throws Exception{
//System.out.println("xxxxx");
List<SuperManager> list=null;


//如果要进行增删改的动作,那么要开启事务
return (List)getHibernateTemplate().execute(new HibernateCallback(){
public Object doInHibernate(Session session){
SQLQuery q = session.createSQLQuery("select sum(sm.id),sm.username from supermanager sm group by sm.username");
q.addScalar("sum(sm.id)",Hibernate.INTEGER);
q.addScalar("sm.username",Hibernate.STRING);
List list1=q.list();
return list1;
}
});

// SuperManager[] superManager = new SuperManager[list.size()];
//         for(int i=0;i<list.size();i++){
//          superManager[i] = (SuperManager)list.get(i);
//         }  
}}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {

 //处理post方式乱码
        request.setCharacterEncoding("utf-8");
        //设置浏览器输出字符编码
        response.setCharacterEncoding("utf-8");
       // PrintWriter writer=response.getWriter();
        //获取flex传递的参数 username password
        try{
      String username = java.net.URLDecoder.decode(request.getParameter("username"), "UTF-8"); 
       // String username = request.getParameter("username");
    
        System.out.println(username);
        
      PrintWriter out=response.getWriter();
        
      //构建一个list存放一些数据用来模拟用户是否存在这一功能
      String xmlContent = "<?xml version='1.0' encoding='utf-8'?><SuperManagers>";
      
      ServletContext servletContext = request.getSession().getServletContext();    
     ApplicationContext ctx = WebApplicationContextUtils.getRequiredWebApplicationContext(servletContext);
     QuerySuperManager l=(QuerySuperManager)ctx.getBean("superManager");     System.out.println(l.getHibernateTemplate());    
     
List list=l.FindSuperManager(username);
if(list.size()>0){
 SuperManager superManager=(SuperManager)list.get(0);
 System.out.println(superManager.getId()+" "+superManager.getUserName()+" "+superManager.getPassword());
 }
 //response.sendRedirect("/fei/index.jsp");
if(list.size()>0){
for(int i=0;i<list.size();i++){
 System.out.println("运行了");
SuperManager superManager=(SuperManager)list.get(i);
xmlContent +="<SuperManager><id>"+superManager.getId()+"</id><userName>"
+superManager.getUserName()+"</userName><password>"+superManager.getPassword()+"</password></SuperManager>";
        //检验用户

}

xmlContent +="</SuperManagers>";}else{
xmlContent="ok";
}
        
        if(list.size()==0)
         out.print(xmlContent); 
        else
         out.println(xmlContent);
            out.flush();   
            out.close(); 
        }catch(Exception e){
         e.printStackTrace();
        }
        
}
问题这样的为什么在servlet里面红色字部分那调用的hibernatetemplate为空
而当运行到FindSuperManager()方法的时候里面输出的hibernatetemplat又存在了 为什么

解决方案 »

  1.   

    是否注入了 sesseionfactory 或者如果是用 默认注入的 是否 设置 autowrite= byname
      

  2.   

    判断是否注入sessionFactory的引用
      

  3.   

    回复2和3楼的 没有注入的话调用FindSuperManager()这个方法的时候里面也有调用getHibernateTemplate()这个时候又存在了明显就是注入了啊
      

  4.   

    ApplicationContext ctx = WebApplicationContextUtils.getRequiredWebApplicationContext(servletContext);这个方法是记得好像是系统启动时候spring会注入到spring的context的吧。///验证登陆
    public List FindSuperManager(final String username) throws Exception{
    //System.out.println("xxxxx");和 ApplicationContext ctx = WebApplicationContextUtils.getRequiredWebApplicationContext(servletContext);
      QuerySuperManager l=(QuerySuperManager)ctx.getBean("superManager");  System.out.println(l.getHibernateTemplate());   
        
    List list=l.FindSuperManager(username);
    你这2是两种不同的QuerySuperManager 获取方式
      

  5.   

    那又怎样呢 注入之后就有了一个实例getHibernateTemplate就得到了初始化 那为什么还为空呢 而且这两种方式调用的是同一个实例
      

  6.   

    没有注入的话调用FindSuperManager()这个方法的时候里面也有调用getHibernateTemplate()这个时候又存在了明显就是注入了啊
      

  7.   

    WebApplicationContextUtils.getRequiredWebApplicationContext
    是直接冲spring的上下文中获取bean
     QuerySuperManager l=(QuerySuperManager)ctx.getBean("superManager");而
    public class QuerySuperManager extends HibernateDaoSupport implements QuerySuperManagerDao {
    是没有spring上下文的去官网上下个 mybatis与spring集成的jar下来
    然后
    public class UserDaoImpl extends SqlSessionDaoSupport implements UserDao {
    public User getUser(String userId) {
    return (User) getSqlSession()
    .selectOne("org.mybatis.spring.sample.mapper.UserMapper.getUser", userId);
    }
    }
    参照里面的配置说明
    <bean id="userMapper" class="org.mybatis.spring.sample.mapper.UserMapperImpl">
    <property name="sqlSessionFactory" ref="sqlSessionFactory" />
    </bean>
      

  8.   

    MyBatis Spring 1.0.0
    参考文档
      

  9.   

    WebApplicationContextUtils 就是一个spring提供给我们获取spring配置信息的东西。
    里面的东西在web项目加载时候spring会通过自己的加载方式把spring的配置信息给设置进去。
    就是spring已经把信息设置到里面去了。
    然后你通过QuerySuperManager l=(QuerySuperManager)ctx.getBean("superManager");
    获取bean。
    但是你继承daosupport时候,spring没有帮你把bean注入到你的dao里面去,所以你要把你需要的东西注入进去
    如sessionfactory简单说就是:WebApplicationContextUtils 系统加载自动配置。
    你要使用你自己的dao需要你自己注入
      

  10.   

    spring上下文是一个配置文件ApplicationContext.xml也就是我启动的时候通过WEB.xml文件读取ApplicationContext.xml这个文件然后给ioc容器注册信息,相关对象得到实例化,也就是HibernateTemplate应该被实例化了可是我在servlet的时候取出来得时候却没有被实例化而在方法里面调用HibernateTemplate却被实例化了这个才是我要问的问题。
      

  11.   

     在我的配置文件里有如下代码
    <bean id="superManager" class="connFlex.impl.QuerySuperManager">
    - <property name="sessionFactory">
      <ref bean="mySessionFactory" /> 
      </property>
      </bean>
    可以看到我是已经把sessionfactory注入进去了正因为这个注入方法里面调用HibernateTemplate才被实例化了不然也一样为空
      

  12.   

    而我现在问题是既然已经实例化了为什么在servlet里获取HibernateTemplate却没被实例化
      

  13.   

    servlet 是由容器自己实例化的。
    这个与一般的bean  dao还是有区别的集中不同的实现方法:
    1.
    把你的QuerySuperManager  设置成静态的。但是set方法 把static 去掉。 (不推荐)2.
    使用你的方法
     ApplicationContext ctx = WebApplicationContextUtils.getRequiredWebApplicationContext(servletContext);
    这个方式就是获取上下文,不是在servlet中注入了。servlet 与普通的bean不一样,生命周期不是由spring管理的,所以spring无法注入,这个就是根本原因所以你的通过2方法可以获取
    QuerySuperManager  ,但是在servlet中无法通过注入QuerySuperManager  
      

  14.   


    如果像你这样说servlet中无法注入  就是无法实例化? 获取的QuerySuperManager 这个不是实例化了?还有
      

  15.   

    还有我通过下面这种方式
    ClassPathResource resource = new ClassPathResource("applicationContext.xml");
    BeanFactory factory = new XmlBeanFactory(resource);
    QuerySuperManager l=(QuerySuperManager)factory.getBean("superManager");
    获取的QuerySuperManager这个实例l却是可以
    也就是System.out.println(l.getHibernateTemplate()); 输出来的是存在的并没有出现空
    我觉得这就是两者不同
    但是为什么通过WEB初始化的就不行呢
      

  16.   

    你的意思是在servlet中只是创建了实例 但是却没有注入sessionfactory?? 要运行到FindSuperManager(username);方法自己调用hibernatetemplate才可以注入sessionfactory?
    为什么创建的实例调用hibernatetemplate时不可以注入sessionfactory呢?
      

  17.   

    不是无法获取,而是不能像dao那样,那么容易注入,当然除了设置为静态的ClassPathResource resource = new ClassPathResource("applicationContext.xml");是自己读取配置文件,获取spring的context加载spring的配置文档。而WebApplicationContextUtils
    这个的实现是spring读取配置文件后设置到这个工具类中。
    区别就是一个是你自己读取配置文件,一个是spring自己读取配置文件。
    你这里写了2行代码,spirng写了一行代码
    加载sping的配置文档种类很多,spring不只是能使用在web项目,但是不是web项目。就可以通过你这中方式加载。你看看spring的官方文档把

    如果像你这样说servlet中无法注入 就是无法实例化?
    servlet 这个类 你没有自己 new 出来吧,就是这个意思,是由tomcat等等容器创建的,
    而不是像自己new的   User u = new User();
      

  18.   

    你这样说依然没解释出到底是什么时候才注入sessionfactory啊 在servlet中都注入不到的话 那调用FindSuperManager方法的时候应该也没注入 那么它里面调用hibernatetemplate应该也是空才对,所以说到底你只是讲了web初始化的方式都没解释清楚这种方式什么时候才会注入sessionfactory
      

  19.   

    我还解释不够清楚啊啊。
    就是一个层次问题:
    所有的QuerySuperManager  都要注入 sessionfactory但是我们分层之后悔吧QuerySuperManager  注入到action 等等 其他调用入口,如果是struts 那么  我们在action 中会把 QuerySuperManager   注入到action中
    public class DemoAction extends BaseAction {
    private QuerySuperManager   querySuperManager   ; //在action中可以注入,要引
    //入spring与struts的jar,再写上set 方法,这样是可以在action中获取得到的,
    //而不不用再去读取配置文件ApplicationContext ctx = WebApplicationContextUtils.getRequiredWebApp
    如果是servlet中
    package com.wsd.servlet;import java.io.IOException;import javax.servlet.ServletException;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;import org.springframework.beans.factory.BeanFactory;
    import org.springframework.context.support.ClassPathXmlApplicationContext;import com.wsd.service.TestService;
    import com.wsd.vo.User;/**
     * Servlet implementation class TestServlet
     */
    public class TestServlet extends HttpServlet {
    private static final long serialVersionUID = 1L; //private QuerySuperManager   querySuperManager  ;//这个是无法通过正常的注入的,你可以设置为静态的变量,获取通过
    //ApplicationContext ctx = WebApplicationContextUtils.getRequiredWebApp ,等等加载配置文件来获取
    //就像我下面的  获取TestService cm = (TestService) factory.getBean("testService");  一样

    private static BeanFactory factory = new ClassPathXmlApplicationContext(
    "applicationContext-*.xml"); /**
     * Default constructor.
     */
    public TestServlet() {
    // TODO Auto-generated constructor stub
    } /**
     * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse
     *      response)
     */
    protected void doGet(HttpServletRequest request,
    HttpServletResponse response) throws ServletException, IOException {
    // TODO Auto-generated method stub
    this.doPost(request, response);
    } /**
     * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse
     *      response)
     */
    protected void doPost(HttpServletRequest request,
    HttpServletResponse response) throws ServletException, IOException { TestService cm = (TestService) factory.getBean("testService");
    for (int i = 0; i < 1; i++) {
    User u = new User();
    u.setId(i + "");
    u.setName("name" + i);
    u.setPass("pass" + i);
    try {
    cm.addUser(u);
    } catch (Exception e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
    }
    // cm.addUser2(u);
    try {
    cm.doUser(u);
    } catch (Exception e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
    }
    // cm.doUser2(u);
    } }}
    所以我们一般是把项目代码层次分清楚;action --service ---dao(你的就是QuerySuperManager )所以在 mapper的都要把 sessionfactory注入进去,不用管 action,service层次。但是你在servlet中获取的应该是 service层,但是servlet中是无法通过注入把service注入进去的(正常情况下),就是servlet中,不能使用正常的像QuerySuperManager 注入sessionfactory一样注入属性,需要变换方式
    明白了吧
      

  20.   


    你的意思是说其实sessionfactory其实在web初始化的时候并没有注入到QuerySuperManager这个里面,而是等调用QuerySuperManager个里面的FindSuperManager方法才能注入进去???
      

  21.   

    不是的。
    如果你的配置文件里面有:
    <bean id="superManager" class="connFlex.impl.QuerySuperManager">
     <property name="sessionFactory">
      <ref bean="mySessionFactory" />  
      </property>
      </bean>说明你已经注入了,如果获取不到 看看其他细节地方是否配置错误了
      

  22.   

    <?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:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"
    xsi:schemaLocation="
    http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
    http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.0.xsd
    http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.0.xsd"> <!-- 配置数据源 -->
    <bean id="dataSource"
           class="org.springframework.jdbc.datasource.DriverManagerDataSource">
    <property name="driverClassName">
    <value>com.mysql.jdbc.Driver</value>
    </property>
    <property name="url">
    <value>jdbc:mysql://localhost:3306/jike?useUnicode=true&amp;characterEncoding=utf8&amp;autoReconnect=true&amp;autoReconnectForPools=true</value>
    </property>
    <property name="username">
    <value>root</value>
    </property>
    <property name="password">
    <value></value>
    </property>


    </bean> <!-- 配置SessionFactory -->
    <bean id="mySessionFactory" 
    class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
    <property name="mappingResources">
    <list>
    <value>pojo/SuperManager.hbm.xml</value>
    </list>
    </property>

    <property name="hibernateProperties">
    <props>
    <prop key="hibernate.dialect">
    org.hibernate.dialect.MySQLDialect
    </prop>
    <prop key="hibernate.show_sql">true</prop>
    <prop key="current_session_context_class">thread</prop>
    <prop key="hibernate.cache.provider_class">
    org.hibernate.cache.EhCacheProvider
    </prop>

    <prop key="hibernate.hbm2ddl.auto">update</prop>

    <!-- 最大连接数 --> 
    <prop key="hibernate.c3p0.max_size">200</prop>  
    <!-- 最小连接数 --> 
    <prop key="hibernate.c3p0.min_size">10</prop>  
    <!-- 获得连接的超时时间,如果超过这个时间,会抛出异常,单位毫秒 --> 
    <prop key="hibernate.c3p0.timeout">120</prop>  
    <!-- 最大的PreparedStatement的数量 --> 
    <prop key="hibernate.c3p0.max_statements">0</prop>  
    <!-- 每隔120秒检查连接池里的空闲连接 ,单位是秒--> 
    <prop key="hibernate.c3p0.idle_test_period">120</prop>  
    <!-- 当连接池里面的连接用完的时候,C3P0一下获取的新的连接数 --> 
    <prop key="hibernate.c3p0.acquire_increment">2</prop>  
    <!-- 每次都验证连接是否可用 --> 
    <prop key="hibernate.c3p0.validate">true</prop> 
    </props>
    </property>

    <property name="dataSource">
    <ref bean="dataSource"/>
    </property>
    </bean> <!-- 配置TransactionManager -->
    <bean id="myTxManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
    <property name="sessionFactory" ref="mySessionFactory" />
    </bean> <!-- 配置事务策略 -->
    <tx:advice id="txAdvice" transaction-manager="myTxManager">
    <tx:attributes>
    <tx:method name="*" propagation="REQUIRED" read-only="true" />
    </tx:attributes>
    </tx:advice> <aop:config proxy-target-class="true">
    <aop:pointcut id="productServiceMethods" expression="execution(* connFlex.impl.*.*(..))" />
    <aop:advisor advice-ref="txAdvice" pointcut-ref="productServiceMethods" />
    </aop:config> <bean id="superManager" 
    class="connFlex.impl.QuerySuperManager">
    <property name="sessionFactory"><ref bean="mySessionFactory"/></property>
    </bean>
    </beans>
    我就是这样配置的没看出错在哪?
      

  23.   

    经过多方努力终于知道什么原因了 HibernateDaoSupport 类中的方法一部分是final方法所以不可以被代理所以才会出现为空