Spring

Estou me deparando com esse erro:

java.lang.NullPointerException
	ProdutosDAO.listar(ProdutosDAO.java:16)
	Controller.listaProdutos(Controller.java:27)

Onde posso estar errando?

ProdutosDAO

public class ProdutosDAO extends HibernateDaoSupport  {

	public Collection listar() {
		return getHibernateTemplate().find("FROM produtos");
	}
	
}

Controller

public class Controller implements Controller{

	public ModelAndView handleRequest(HttpServletRequest request,
			HttpServletResponse response) throws ServletException, IOException {
		Collection lista = listaProdutos();
		request.setAttribute("lista", lista);
		return new ModelAndView("/pages/index.jsp");
	}
	
	public Collection listaProdutos() {
		ProdutosDAO dao = new ProdutosDAO();
		return dao.listar();
	}
}

Produtos.hbm.xml

<hibernate-mapping package="vo">

        <class name="ProdutosVO" 
            table="produtos">
                
                <id name="codigo" column="cod_prod">
                    <generator class="increment"/>
                </id>
                                
                <property name="nome" column="nome_prod" />
                
        </class>  

</hibernate-mapping>

loja-hibernate.xml

<beans>
	<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/loja</value>
		</property>
		<property name="username">
			<value>root</value>
		</property>
		<property name="password">
			<value>root</value>
		</property>
	</bean>

	<bean id="sessionFactory"
		class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">

		<property name="dataSource">
			<ref local="dataSource" />
		</property>
		<property name="mappingResources">
			<list>
				<value>
					Artistas.hbm.xml
				</value>
			</list>
		</property>
		<property name="hibernateProperties">
			<props>
				<prop key="hibernate.dialect">
					org.hibernate.dialect.MySQLDialect
				</prop>
				<prop key="hibernate.hbm2ddl.auto">update</prop>
			</props>
		</property>
	</bean>

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

	<bean id="produtosDAO" class="ProdutosDAO">
		<property name="sessionFactory">
			<ref local="sessionFactory" />
		</property>
	</bean>

web.xml

<servlet>
		<servlet-name>loja</servlet-name>
		<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
		<load-on-startup>1</load-on-startup>
	</servlet>
	
	<servlet-mapping>
		<servlet-name>loja</servlet-name>
		<url-pattern>*.action</url-pattern>
	</servlet-mapping>	
	
	<welcome-file-list>
		<welcome-file>
			index.jsp
		</welcome-file>
	</welcome-file-list>
  	
  	<listener>
        <listener-class>
            org.springframework.web.context.ContextLoaderListener
        </listener-class>
    </listener>

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

Aparentemente o Spring não está conseguindo injetar a instância do DAO no controller, pois você não colocou o método set para que o spring possa injetar.

Verifique se você possui esse método set no controller.

Eu tenho ele sim no meu dao, veja:

public class ProdutosDAO extends HibernateDaoSupport  {   
  
   private ProdutosDAO dao;   
	  
   public void setProdutosDAO(ProdutosDAO dao) {   
        this.dao = dao;   
   }

    public Collection listar() {   
        return getHibernateTemplate().find("FROM produtos");   
    }   
       
}

O que mais que deve estar faltando?

Você tá confundindo um pouco as coisas. Não é responsabilidade do controler obter uma instância do DAO, logo você não deve fazer isso. Lembre-se do velho conceito de hollywood:

Portanto não é preciso instânciar o DAO:

public Collection listaProdutos() { ProdutosDAO dao = new ProdutosDAO(); return dao.listar(); }

Essa classe poderia ser escrita assim:

    public class Controller implements Controller {  
   
        private ProdutosDAO dao;
   
        public ModelAndView handleRequest(HttpServletRequest request,  
                HttpServletResponse response) throws ServletException, IOException {  
            Collection lista = listaProdutos();  
            request.setAttribute("lista", lista);  
            return new ModelAndView("/pages/index.jsp");  
        }  
          
       public Collection listaProdutos() {  
           return dao.listar();  
       }  

       public void setProdutosDAO(ProdutosDAO dao) {     
         this.dao = dao;     
       } 

  }  

O código que você passou é estranho. Você declara uma propriedade ProdutosDAO dentro da própria classe ProdutosDAO.

A propriedade que faz referência ao DAO deve ser declarada no controle, de forma que o Spring irá injetar a instância da classe ProdutosDAO e assim não ocorrerá a NPE.

Aconselho você dar mais uma lida sobre injeção de dependências (IoC).

Qualquer dúvida, não deixe de postar aqui.

Fiz as alterações que vc me disse, mas mesmo assim o erro continua.

ProdutosDAO

public class ProdutosDAO extends HibernateDaoSupport {

	public Collection listar() {
		return getHibernateTemplate().find("FROM produtos");
	}

}

Controller

public class Controller implements Controller{

	private ProdutosDAO dao;
	
	public void setProdutosDAO(ProdutosDAO dao) {       
		this.dao = dao;       
	}
	public ModelAndView handleRequest(HttpServletRequest request,
			HttpServletResponse response) throws ServletException, IOException {
		Collection lista = listar();
		request.setAttribute("lista", lista);
		return new ModelAndView("/pages/index.jsp");
	}
	
	public Collection listar() {
		return dao.listar();
	}

loja-hibernate.xml

...
<bean id="produtosDAO" class="ProdutosDAO">   
        <property name="sessionFactory">   
            <ref local="sessionFactory" />   
        </property>   
    </bean>
...

Cadê o applicationContext.xml ?

Coloque assim a declaração do bean:

<bean id="dao" class="ProdutosDAO"> <property name="sessionFactory"> <ref local="sessionFactory" /> </property> </bean>

&lt;beans&gt;
	
	&lt;bean name="/index.action" class="Controller"/&gt;
	
&lt;/beans&gt;

Faz esse teste aí de cima e me diz o resultado. Essa sua organização dos arquivos está bem estranha.

Nao funcionou…minha hierarquia ta a seguinte:

loja
   src
       Controller.java
       ProdutosDAO.java
       ProdutosVO.java
       Produtos.hbm.xml
   war
       WEB-INF
            classes
            lib
            loja-hibernate.xml
            web.xml
            loja-servlet.xml
   build.xml
   build.properties

Parece que está ok. O erro continua ocorrendo na mesma linha ?

Continua sim…parece q o metodo esta retornando nulo…O que tenho q fazer agora?

Consegui arrumar…Fiz o seguinte:
na minha classe DAO mudei o metodo para

ProdutosDAO

public Collection listar() {        
		return getHibernateTemplate().loadAll(ArtistasVO.class);   
	}

e no meu loja-servlet.xml coloquei

&lt;bean name="/index.action" class="Controller"&gt;
	 	&lt;property name="produtosDAO" ref="dao"/&gt;
	&lt;/bean&gt;

T mais…Vlw pelas dicas