Erro no Ajax do selectOneMenu para popular um Ring

Fala galera…

Estou desenvolvendo uma loja virtual para entregar na facu (recuperação!!!).
A parte de cadastro está ok. Comecei a fazer a página dos produtos e a ideia é mais ou menos esta:
Tenho um selectOneMenu com ajax populado com os tipos de produtos, que servirá como filtro para o usuário visualizar os produtos por categoria. O ring exibirá os produtos e ao clicar no produto do centro, ele exibe uma dialog com os detalhes e o botão para confirmar a compra.
Após um longo e tenebroso inverno, e várias googadas não consegui achar algo para me ajudar e claro vim aqui pedir socorro. Pesquisei aqui também para achar algum tópico e nada.

Segue abaixo os códigos:

PÁGINA XHTML:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:ui="http://java.sun.com/jsf/facelets"
      xmlns:h="http://java.sun.com/jsf/html"
      xmlns:p="http://primefaces.org/ui"
      xmlns:f="http://java.sun.com/jsf/core">

    <ui:decorate template="/templates/loja.xhtml" >

        <ui:define name="content">
            
            <h:form id="form1">
                <p:selectOneMenu value="#{promocoesBean.codigo}" label="Categoria" effect="fade" styleClass="combo-promo" > 
                <f:selectItem  itemLabel="Selecione" itemValue="" />  
                <f:selectItems value="#{promocoesBean.categorias}" var="categoria" itemLabel="#{categoria.descricao}" itemValue="#{categoria.categoriaId}"/>
                <p:ajax update=":form2:ring" listener="#{promocoesBean.carregarProdutos()}" />
                </p:selectOneMenu>
            </h:form>
            
            <h:form id="form2">                
            <p:ring id="ring" value="#{promocoesBean.produtos}" var="produto" styleClass="image-ring ring-promo" easing="easeInQuart">                  
                    <p:panelGrid columns="1" style="text-align:center;" >  
                        <p:graphicImage id="imagem" library="images" name="#{produto.imagem}" styleClass="image-produto"/>
                        <p:commandButton update=":form2:janela" value="+ Detalhes" oncomplete="dlg.show()">  
                            <f:setPropertyActionListener value="#{produto}" target="#{promocoesBean.produtoDTO}" />  
                        </p:commandButton>  
                    </p:panelGrid> 
                </p:ring>

                <p:dialog id="dialog" widgetVar="dlg" showEffect="fade" hideEffect="fade" modal="false" width="380">  
                    <p:outputPanel id="janela" style="text-align: center;" layout="block">  
                    <p:panelGrid  columns="1" rendered="#{not empty promocoesBean.produtoDTO}" style="width: 350px;">  

                    <p:graphicImage library="images" name="#{promocoesBean.produtoDTO.imagem}" styleClass="image-produto"/>
                    <p:outputLabel   value="Código: #{promocoesBean.produtoDTO.produtoId}" styleClass="label-codigo" />
                    <p:outputLabel   value="Produto: #{promocoesBean.produtoDTO.descricao}" styleClass="label-descricao"/>
                    <p:outputLabel   value="Preço: R$ #{promocoesBean.produtoDTO.preco}" styleClass="label-preco" />
                    <p:commandButton value="Comprar" action="#"/>

                        </p:panelGrid>  
                    </p:outputPanel>  
                </p:dialog>
            </h:form>
            
        </ui:define>

        <ui:define name="right">
            <h:form>
                <a href="http://www.amd.com" target="_blank">
                   <p:graphicImage id="amd" library="images" name="banner_amd.png" styleClass="banner" title="AMD Inc."/>
                </a>
            </h:form> 
        </ui:define>

    </ui:decorate>

</html>

MANAGEDBEAN:


@ManagedBean(name = "promocoesBean")
public final class PromocoesBean {

    private ProdutoDTO produtoDTO;
    private CategoriaDTO categoriaDTO;
    private List produtos;
    private List categorias;
    private int codigo;


    public PromocoesBean() throws SQLException, UnsupportedEncodingException {
        carregarCategorias();
        carregarProdutos();
    }

    public void carregarCategorias() throws SQLException, UnsupportedEncodingException {
        CategoriaDAO categoriaDAO = new CategoriaDAO();
        setCategorias(categoriaDAO.listarCategorias());
    }

    public void carregarProdutos() throws SQLException, UnsupportedEncodingException {
        ProdutoDAO produtoDAO = new ProdutoDAO();
        getProdutoDTO().getCategoriaDTO().setCategoriaId(codigo);
        setProdutos(produtoDAO.listarPorCategoria(getProdutoDTO()));
    }

    /**
     * @return produtoDTO
     */
    public ProdutoDTO getProdutoDTO() {
        if (produtoDTO == null){ 
            produtoDTO = new ProdutoDTO(); 
        }
        return produtoDTO;
    }

    /**
     * @return categoriaDTO
     */
    public CategoriaDTO getCategoriaDTO() {
        if (categoriaDTO == null) {
            categoriaDTO = new CategoriaDTO();
        }
        return categoriaDTO;
    }

PRODUTODAO

    /**
     * Lista Os produtos por categorias.
     * @param produtoDTO - com todos os atributos preenchidos.
     * @throws SQLException
     */
    public List listarPorCategoria(ProdutoDTO produtoDTO) throws SQLException {

        List allProdutos = new ArrayList();

         if (produtoDTO != null) {

            List listaProdutos = new ArrayList();
            String sql = "SELECT P.PRODUTO_ID, P.DESCRICAO, P.PRECO, P.ATIVO, P.ESTOQUE, P.IMAGEM FROM PRODUTOS P "
                       + "INNER JOIN CATEGORIAS C ON C.CATEGORIA_ID = P.CATEGORIA_ID "
                       + "WHERE C.CATEGORIA_ID = ? "
                       + "ORDER BY PRODUTO_ID";
            PreparedStatement pstmt = getDatabase().openConnection().prepareStatement(sql);
            pstmt.setInt(1, produtoDTO.getCategoriaDTO().getCategoriaId());
            ResultSet rs = pstmt.executeQuery();

            while (rs.next()) {
                produto = new ProdutoDTO();
                produto.setProdutoId(rs.getInt("PRODUTO_ID"));
                produto.setDescricao(rs.getString("DESCRICAO"));
                produto.setPreco(rs.getFloat("PRECO"));
                produto.setEstoque(rs.getInt("ESTOQUE"));
                produto.setAtivo(rs.getBoolean("ATIVO"));
                produto.setImagem(rs.getString("IMAGEM"));
                listaProdutos.add(produto);
            }

            getDatabase().closeConnection();
            return listaProdutos;
            
        } else {
            allProdutos = listarProdutos();
        }
        return allProdutos;
    }

Se eu tento utilizar o objeto na página xhtml acontece esses 2 erros:

Sem instanciar o objeto:

GRAVE: Servlet.service() for servlet [Faces Servlet] in context with path [/LojaVirtualPrimefaces] threw exception [/loja/promocoes.xhtml @14,153 value="#{promocoesBean.produtoDTO.categoriaDTO.categoriaId}": Target Unreachable, ‘produtoDTO’ returned null] with root cause
javax.el.PropertyNotFoundException: /loja/promocoes.xhtml @14,153 value="#{promocoesBean.produtoDTO.categoriaDTO.categoriaId}": Target Unreachable, ‘produtoDTO’ returned null
at com.sun.faces.facelets.el.TagValueExpression.getType(TagValueExpression.java:100)
at org.primefaces.renderkit.InputRenderer.findImplicitConverter(InputRenderer.java:170)
at org.primefaces.renderkit.InputRenderer.getOptionAsString(InputRenderer.java:156)
at org.primefaces.component.selectonemenu.SelectOneMenuRenderer.encodeOption(SelectOneMenuRenderer.java:347)
at org.primefaces.component.selectonemenu.SelectOneMenuRenderer.encodeSelectItems(SelectOneMenuRenderer.java:333)
at org.primefaces.component.selectonemenu.SelectOneMenuRenderer.encodeInput(SelectOneMenuRenderer.java:114)
at org.primefaces.component.selectonemenu.SelectOneMenuRenderer.encodeMarkup(SelectOneMenuRenderer.java:91)
at org.primefaces.component.selectonemenu.SelectOneMenuRenderer.encodeEnd(SelectOneMenuRenderer.java:65)
at javax.faces.component.UIComponentBase.encodeEnd(UIComponentBase.java:875)
at javax.faces.component.UIComponent.encodeAll(UIComponent.java:1763)
at javax.faces.render.Renderer.encodeChildren(Renderer.java:168)
at javax.faces.component.UIComponentBase.encodeChildren(UIComponentBase.java:845)
at org.primefaces.renderkit.CoreRenderer.renderChild(CoreRenderer.java:59)
at org.primefaces.renderkit.CoreRenderer.renderChildren(CoreRenderer.java:47)
at org.primefaces.component.layout.LayoutUnitRenderer.encodeEnd(LayoutUnitRenderer.java:51)
at javax.faces.component.UIComponentBase.encodeEnd(UIComponentBase.java:875)
at javax.faces.component.UIComponent.encodeAll(UIComponent.java:1763)
at javax.faces.component.UIComponent.encodeAll(UIComponent.java:1759)
at javax.faces.component.UIComponent.encodeAll(UIComponent.java:1759)
at javax.faces.component.UIComponent.encodeAll(UIComponent.java:1759)
at com.sun.faces.application.view.FaceletViewHandlingStrategy.renderView(FaceletViewHandlingStrategy.java:401)
at com.sun.faces.application.view.MultiViewHandler.renderView(MultiViewHandler.java:131)
at com.sun.faces.lifecycle.RenderResponsePhase.execute(RenderResponsePhase.java:121)
at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:101)
at com.sun.faces.lifecycle.LifecycleImpl.render(LifecycleImpl.java:139)
at javax.faces.webapp.FacesServlet.service(FacesServlet.java:410)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:305)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:225)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:123)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:472)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:168)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:98)
at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:927)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:407)
at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1001)
at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:585)
at org.apache.tomcat.util.net.AprEndpoint$SocketProcessor.run(AprEndpoint.java:1770)
at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
at java.lang.Thread.run(Thread.java:662)

Com a instancia do objeto:

GRAVE: Servlet.service() for servlet [Faces Servlet] in context with path [/LojaVirtualPrimefaces] threw exception [String index out of range: 0] with root cause
java.lang.StringIndexOutOfBoundsException: String index out of range: 0
at java.lang.String.charAt(String.java:686)
at com.sun.faces.application.resource.ResourceManager.trimLeadingSlash(ResourceManager.java:490)
at com.sun.faces.application.resource.ResourceManager.doLookup(ResourceManager.java:247)
at com.sun.faces.application.resource.ResourceManager.findResource(ResourceManager.java:185)
at com.sun.faces.application.resource.ResourceHandlerImpl.createResource(ResourceHandlerImpl.java:143)
at com.sun.faces.application.resource.ResourceHandlerImpl.createResource(ResourceHandlerImpl.java:123)
at javax.faces.application.ResourceHandlerWrapper.createResource(ResourceHandlerWrapper.java:96)
at org.primefaces.component.graphicimage.GraphicImageRenderer.getImageSrc(GraphicImageRenderer.java:66)
at org.primefaces.component.graphicimage.GraphicImageRenderer.encodeEnd(GraphicImageRenderer.java:45)
at javax.faces.component.UIComponentBase.encodeEnd(UIComponentBase.java:875)
at javax.faces.component.UIComponent.encodeAll(UIComponent.java:1763)
at org.primefaces.component.panelgrid.PanelGridRenderer.encodeDynamicBody(PanelGridRenderer.java:92)
at org.primefaces.component.panelgrid.PanelGridRenderer.encodeBody(PanelGridRenderer.java:60)
at org.primefaces.component.panelgrid.PanelGridRenderer.encodeEnd(PanelGridRenderer.java:49)
at javax.faces.component.UIComponentBase.encodeEnd(UIComponentBase.java:875)
at org.primefaces.renderkit.CoreRenderer.renderChild(CoreRenderer.java:63)
at org.primefaces.renderkit.CoreRenderer.renderChildren(CoreRenderer.java:47)
at org.primefaces.component.outputpanel.OutputPanelRenderer.encodeEnd(OutputPanelRenderer.java:46)
at javax.faces.component.UIComponentBase.encodeEnd(UIComponentBase.java:875)
at org.primefaces.renderkit.CoreRenderer.renderChild(CoreRenderer.java:63)
at org.primefaces.renderkit.CoreRenderer.renderChildren(CoreRenderer.java:47)
at org.primefaces.component.dialog.DialogRenderer.encodeContent(DialogRenderer.java:172)
at org.primefaces.component.dialog.DialogRenderer.encodeMarkup(DialogRenderer.java:101)
at org.primefaces.component.dialog.DialogRenderer.encodeEnd(DialogRenderer.java:43)
at javax.faces.component.UIComponentBase.encodeEnd(UIComponentBase.java:875)
at javax.faces.component.UIComponent.encodeAll(UIComponent.java:1763)
at javax.faces.render.Renderer.encodeChildren(Renderer.java:168)
at javax.faces.component.UIComponentBase.encodeChildren(UIComponentBase.java:845)
at org.primefaces.renderkit.CoreRenderer.renderChild(CoreRenderer.java:59)
at org.primefaces.renderkit.CoreRenderer.renderChildren(CoreRenderer.java:47)
at org.primefaces.component.layout.LayoutUnitRenderer.encodeEnd(LayoutUnitRenderer.java:51)
at javax.faces.component.UIComponentBase.encodeEnd(UIComponentBase.java:875)
at javax.faces.component.UIComponent.encodeAll(UIComponent.java:1763)
at javax.faces.component.UIComponent.encodeAll(UIComponent.java:1759)
at javax.faces.component.UIComponent.encodeAll(UIComponent.java:1759)
at javax.faces.component.UIComponent.encodeAll(UIComponent.java:1759)
at com.sun.faces.application.view.FaceletViewHandlingStrategy.renderView(FaceletViewHandlingStrategy.java:401)
at com.sun.faces.application.view.MultiViewHandler.renderView(MultiViewHandler.java:131)
at com.sun.faces.lifecycle.RenderResponsePhase.execute(RenderResponsePhase.java:121)
at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:101)
at com.sun.faces.lifecycle.LifecycleImpl.render(LifecycleImpl.java:139)
at javax.faces.webapp.FacesServlet.service(FacesServlet.java:410)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:305)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:225)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:123)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:472)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:168)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:98)
at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:927)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:407)
at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1001)
at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:585)
at org.apache.tomcat.util.net.AprEndpoint$SocketProcessor.run(AprEndpoint.java:1770)
at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
at java.lang.Thread.run(Thread.java:662)

E caso eu use uma variável int para pegar o id da categoria não dá erro, mas a variável sempre vem igual a zero.

Estou utilizando primefaces 3.5, win 7, netbeans 7.2 e apache-tomcat-7.0.29
Agradeço a ajuda galera… Obrigado pela atenção