Solucionado (ver solução)
Solucionado
(ver solução)
15
respostas

Duvida com o selectOneMenu

Boa tarde, estou com uma duvida, tenho o meu select one menu, e nele eu to trazendo uma lista de marcas.

<p:selectOneMenu id="marca" value="#{produtoBean.marca.marca}"
                        required="true" requiredMessage="Marca obrigatória">
                        <f:selectItem itemValue="" itemLabel="Selecione a opção" />
                        <f:selectItems value="#{produtoBean.marcas}" var="marca"
                            itemLabel="#{marca.codigo}" itemValue="#{marca.marca}" />
                    </p:selectOneMenu>

depois tenho o meu outro xhtml que adiciona as marcas.

<ui:composition template="/template/_template.xhtml">
    <ui:define name="conteudo">
        <p:growl id="mensagem" sticky="true"/>
        <h:form>
            <p:fieldset legend="Adicionar Marcas">
                <h:panelGrid columns="4">
                    <p:outputLabel value="Nome da marca: " for="marca" />
                    <p:inputText id="marca" value="#{marcaBean.marca.marca}"
                        required="true" requiredMessage="marca obrigatória" size="50" />
                    <p:commandButton value="Salvar"
                        actionListener="#{marcaBean.adicionar}"
                        update=":mensagem :formularioCadastro" />
                    <p:commandButton value="Voltar"
                        action="#{marcaBean.formularioPrincipal}" immediate="true" />
                </h:panelGrid>
            </p:fieldset>
        </h:form>

        <h:form id="formularioCadastro">
            <p:dataTable var="marca" value="#{marcaBean.marcas}"
                emptyMessage="Nenhuma marca encontrada">
                <f:facet name="header">
                Tabela Marcas
            </f:facet>
                <p:column headerText="Marca">
                    <h:outputText value="#{marca.marca}" />
                </p:column>
            </p:dataTable>
        </h:form>

    </ui:define>
</ui:composition>

</html>

ok só que ai ta ocorrendo uma situação que não sei sair dela, por exemplo tenho 2 marcas adicionadas, ai vo no meu pruduto para adicionar e no campo marca ta la as 2 marcas, escolha minha marca desejada e salvo o produto, e automaticamente, aonde tinha 2 marcas incrementa mais a marca que eu escolhi na hora de salvar o produto, e o pior é a mesma marca que ja tinha para escolher. Queria que só mostrasse uma marca nova marca no meu select one menu quando eu adicionasse ela no meu formularaio de marcas, e não quando eu for salvar um produto e escolher uma marca e salvar o produto e adicionasse essa marca. Pra ficar mais claro por exemplo tenho 2 marcas. tim e vivo, no meu selectOneMenu vo la salvar o meu produto e no campo marca ta as 2 marcas, escolho a marca vivo, e salvo o produto, salvei o produto e depois o meu selectOneMenu vai tar assim. tim vivo e vivo. como sair desse problema?

15 respostas

Alisson, posta teu ManagedBean e a classe responsável pela persistência.

Tenho minha classe do produto que tem um atributo do tipo marca. E tenho minha classe marca.

@ManagedBean
@SessionScoped
public class ProdutoBean implements Serializable {

    private static final long serialVersionUID = 1L;

    private Produto produto;
    private Marca marca = new Marca();
    private List<Produto> produtos = new ProdutoDao().listarTodos();


    public List<Produto> getProdutos() {
        if (produtos == null) {
            new ProdutoDao().listarTodos();
        }
        return produtos;
    }

    public Marca getMarca() {
        return marca;
    }

    public void setMarca(Marca marca) {
        this.marca = marca;
    }

    public Produto getProduto() {
        if (produto == null) {
            produto = new Produto();
        }
        return produto;
    }

    public void setProduto(Produto produto) {
        this.produto = produto;
    }

    public void salvar() {
        if(produto.getCodigo() == null) {
            produto.setMarca(marca);
            new ProdutoDao().adicionar(produto, marca);
            new MensagemUtil().mensagemInfo("Produto adicionado com sucesso");
        } else {
            new ProdutoDao().atualiza(produto, marca);
            new MensagemUtil().mensagemInfo("Produto atualizado com sucesso");
        }
        this.produto = new Produto();
        this.marca = new Marca();
    }

    public void remover(Produto produto) {
        new ProdutoDao().remover(produto);
        new MensagemUtil().mensagemInfo("Excluido com sucesso");
        produtos = new ProdutoDao().listarTodos();
    }

    public Redirecionador carregar(Produto produto) {
        this.produto = produto;
        Marca marca2 = produto.getMarca();
        this.marca = marca2;
        return new Redirecionador("produto");
    }

    public void setProdutos(List<Produto> produtos) {
        this.produtos = produtos;
    }

    public Redirecionador formularioProduto() {
        return new Redirecionador("produto");
    }

    public Redirecionador formularioTabela() {
        this.produto = new Produto();
        this.marca = new Marca();
        produtos = new ProdutoDao().listarTodos();
        return new Redirecionador("produtoPesquisa");
    }

    public List<Marca> getMarcas() {
        return new MarcaDao().lstMarcas();
    }

Aqui esta minha classe marca

@ManagedBean
@ViewScoped
public class MarcaBean implements Serializable{

    private static final long serialVersionUID = 1L;

    private Marca marca;

    public Marca getMarca() {
        if(marca == null) {
            marca = new Marca();
        }
        return marca;
    }

    public void setMarca(Marca marca) {
        this.marca = marca;
    }

    public void adicionar() {
        if(marca.getCodigo() == null) {
            new MarcaDao().adicionar(marca);
            new MensagemUtil().mensagemInfo("Marca cadastrado com sucesso");
        } else {
            new MarcaDao().atualizar(marca);
            new MensagemUtil().mensagemInfo("Marca atualizada  com sucesso");
        }
        this.marca = new Marca();
    }

    public void remover(Marca marca) {
        new MarcaDao().remover(marca);
        new MensagemUtil().mensagemInfo("Marca removida com sucesso");
    }

    public void carregar(Marca marca) {
        new MarcaDao().atualizar(marca);
        this.marca = marca;
    }

    public Redirecionador formularioPrincipal() {
        return new Redirecionador("principal");
    }

    public List<Marca> getMarcas() {
        return new MarcaDao().lstMarcas();
    }

}

Posta o ProdutoDao e MarcaDao também...

MarcaDao

import java.util.List;

import javax.persistence.EntityManager;

import br.com.bercalini.borracharia.modelo.Marca;

public class MarcaDao {

    public void adicionar(Marca marca) {
        EntityManager em = new JPAUtil().geEntityManager();
        em.getTransaction().begin();
        em.persist(marca);
        em.getTransaction().commit();
        em.close();
    }

    public void remover(Marca marca) {
        EntityManager em = new JPAUtil().geEntityManager();
        em.getTransaction().begin();
        em.remove(em.merge(marca));
        em.getTransaction().commit();
        em.close();
    }

    public void atualizar(Marca marca) {
        EntityManager em = new JPAUtil().geEntityManager();
        em.getTransaction().begin();
        em.merge(marca);
        em.getTransaction().commit();
        em.close();
    }

    @SuppressWarnings("unchecked")
    public List<Marca> lstMarcas() {
        EntityManager em = new JPAUtil().geEntityManager();
         List<Marca> lista = em.createNamedQuery("Marca.lista").getResultList();
         em.close();
         return lista;
    }

}
import java.util.List;

import javax.persistence.EntityManager;

import br.com.bercalini.borracharia.modelo.Marca;
import br.com.bercalini.borracharia.modelo.Produto;

public class ProdutoDao {

    public void adicionar(Produto produto,Marca marca) {
        EntityManager em = new JPAUtil().geEntityManager();
        em.getTransaction().begin();
        em.persist(produto);
        em.persist(marca);
        em.getTransaction().commit();
        em.close();
    }

    public void remover(Produto produto) {
        EntityManager em = new JPAUtil().geEntityManager();
        em.getTransaction().begin();
        em.remove(em.merge(produto));
        em.getTransaction().commit();
        em.close();
    }

    public void atualiza(Produto produto, Marca marca) {
        EntityManager em = new JPAUtil().geEntityManager();
        em.getTransaction().begin();
        em.merge(produto);
        em.merge(marca);
        em.getTransaction().commit();
        em.close();
    }

    @SuppressWarnings("unchecked")
    public List<Produto> listarTodos() {
        EntityManager em = new JPAUtil().geEntityManager();
        List<Produto> resultado = em.createNamedQuery("Produto.listarTodos").getResultList();
        return resultado;
    }
}

ProdutoDao

Alisson, recomendo que você faça o ManagedBean acessar apenas um DAO, de modo que o MarcaDao faça o CRUD apenas de objetos do tipo Marca e que ProdutoDao faça o CRUD apenas de objetos do tipo Produto.

Suponha as duas classes:

class Produto {
    Integer id;
    @OneToOne
    @JoinColumn(name = "marca_id", nullable = false)
    Marca marca;
    // getters and setters
}
class Marca {
    Integer id;
    String marca;
    // getters and setters
}

Quando você fizer

public void adicionar(Produto produto) {
        EntityManager em = new JPAUtil().geEntityManager();
        em.getTransaction().begin();
        em.persist(produto);
        em.getTransaction().commit();
        em.close();
    }

Seu objeto do tipo Produto será persistido já com o vínculo do objeto Marca, ou seja, com o id do objeto marca em uma das colunas da tabela Produto.

Dessa forma, você não precisa usar um DAO para persistir ou atualizar dois objetos distintos. Não recomendo fazer essa prática, de usar um DAO para gerenciar objetos diferentes.

Considerando que você tenha apenas duas camadas (view e model), a ideia é que ProdutoBean acesse apenas ProdutoDAO para persistir objetos. Se você tivesse três camadas (view, control e model), seria: ProdutoBean acessando apenas ProdutoService e apenas ProdutoService acessando ProdutoDAO.

Perceba que é o mapeamento da JPA que torna as coisas mais simples. O vínculo feito entre Produto e Marca reside no mapeamento e não na aplicação cuidar disso, fica mais transparente. Se você não entender bem os mapeamentos (@OneToOne e @JoinColumn), recomendo que dê um pause nesse de JSF e faça o o curso Java e JPA: Persista seus objetos com a JPA2 e Hibernate (https://cursos.alura.com.br/course/jpa) e, depois, retorne para o de JSF. Você vai ver que as coisas ficam mais fáceis quando você faz os mapeamentos corretos.

Se não conseguir, posta aqui de novo (dessa vez com tuas classes Produto e Marca), pra gente dar uma olhada no relacionamento.

Abraço.

Manoel perfeito, entendi claramente a sua posição, então no meu daoProduto so adicionarei o produto, e com a anotação.

@OneToOne
    @JoinColumn(name = "marca_id", nullable = false)

seria uma junção de tabela? ai quando eu adiciono o meu produto com essa anotação e se tiver tudo certo no meu bean adicionara o produto e a marca com o id da marca dentro do meu produto? seria algo parecido com isso? então vou fazer essas modificações aqui e ver como ira ficar, vou deixar o tópico aberto amigo, caso tenho problemas postarei aqui, muito obrigado!!!

Manoel fiz a alteração e o erro foi esse.

ADVERTÊNCIA: javax.persistence.RollbackException: Error while committing the transaction
javax.el.ELException: javax.persistence.RollbackException: Error while committing the transaction
    at org.apache.el.parser.AstValue.invoke(AstValue.java:292)
    at org.apache.el.MethodExpressionImpl.invoke(MethodExpressionImpl.java:273)
    at javax.faces.event.MethodExpressionActionListener.processAction(MethodExpressionActionListener.java:149)
    at javax.faces.event.ActionEvent.processListener(ActionEvent.java:88)
    at javax.faces.component.UIComponentBase.broadcast(UIComponentBase.java:814)
    at javax.faces.component.UICommand.broadcast(UICommand.java:300)
    at javax.faces.component.UIViewRoot.broadcastEvents(UIViewRoot.java:790)
    at javax.faces.component.UIViewRoot.processApplication(UIViewRoot.java:1282)
    at com.sun.faces.lifecycle.InvokeApplicationPhase.execute(InvokeApplicationPhase.java:81)
    at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:101)
    at com.sun.faces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:198)
    at javax.faces.webapp.FacesServlet.service(FacesServlet.java:658)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:303)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
    at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:218)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:122)
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:505)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:169)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:103)
    at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:956)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:116)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:442)
    at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1082)
    at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:623)
    at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:318)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
    at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
    at java.lang.Thread.run(Unknown Source)
Caused by: javax.persistence.RollbackException: Error while committing the transaction
    at org.hibernate.ejb.TransactionImpl.commit(TransactionImpl.java:92)
    at br.com.bercalini.borracharia.Dao.ProdutoDao.adicionar(ProdutoDao.java:16)
    at br.com.bercalini.borracharia.bean.ProdutoBean.salvar(ProdutoBean.java:56)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
    at java.lang.reflect.Method.invoke(Unknown Source)
    at org.apache.el.parser.AstValue.invoke(AstValue.java:279)
    ... 31 more
Caused by: java.lang.IllegalStateException: org.hibernate.TransientPropertyValueException: object references an unsaved transient instance - save the transient instance before flushing: br.com.bercalini.borracharia.modelo.Produto.marca -> br.com.bercalini.borracharia.modelo.Marca
    at org.hibernate.ejb.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1374)
    at org.hibernate.ejb.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1300)
    at org.hibernate.ejb.TransactionImpl.commit(TransactionImpl.java:80)
    ... 38 more
Caused by: org.hibernate.TransientPropertyValueException: object references an unsaved transient instance - save the transient instance before flushing: br.com.bercalini.borracharia.modelo.Produto.marca -> br.com.bercalini.borracharia.modelo.Marca
    at org.hibernate.engine.spi.CascadingAction$8.noCascade(CascadingAction.java:380)
    at org.hibernate.engine.internal.Cascade.cascade(Cascade.java:176)
    at org.hibernate.event.internal.AbstractFlushingEventListener.cascadeOnFlush(AbstractFlushingEventListener.java:160)
    at org.hibernate.event.internal.AbstractFlushingEventListener.prepareEntityFlushes(AbstractFlushingEventListener.java:151)
    at org.hibernate.event.internal.AbstractFlushingEventListener.flushEverythingToExecutions(AbstractFlushingEventListener.java:88)
    at org.hibernate.event.internal.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:51)
    at org.hibernate.internal.SessionImpl.flush(SessionImpl.java:1213)
    at org.hibernate.internal.SessionImpl.managedFlush(SessionImpl.java:402)
    at org.hibernate.engine.transaction.internal.jdbc.JdbcTransaction.beforeTransactionCommit(JdbcTransaction.java:101)
    at org.hibernate.engine.transaction.spi.AbstractTransactionImpl.commit(AbstractTransactionImpl.java:175)
    at org.hibernate.ejb.TransactionImpl.commit(TransactionImpl.java:75)
    ... 38 more

nov 16, 2016 2:49:49 PM com.sun.faces.context.AjaxExceptionHandlerImpl handlePartialResponseError
GRAVE: javax.persistence.RollbackException: Error while committing the transaction
    at org.hibernate.ejb.TransactionImpl.commit(TransactionImpl.java:92)
    at br.com.bercalini.borracharia.Dao.ProdutoDao.adicionar(ProdutoDao.java:16)
    at br.com.bercalini.borracharia.bean.ProdutoBean.salvar(ProdutoBean.java:56)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
    at java.lang.reflect.Method.invoke(Unknown Source)
    at org.apache.el.parser.AstValue.invoke(AstValue.java:279)
    at org.apache.el.MethodExpressionImpl.invoke(MethodExpressionImpl.java:273)
    at javax.faces.event.MethodExpressionActionListener.processAction(MethodExpressionActionListener.java:149)
    at javax.faces.event.ActionEvent.processListener(ActionEvent.java:88)
    at javax.faces.component.UIComponentBase.broadcast(UIComponentBase.java:814)
    at javax.faces.component.UICommand.broadcast(UICommand.java:300)
    at javax.faces.component.UIViewRoot.broadcastEvents(UIViewRoot.java:790)
    at javax.faces.component.UIViewRoot.processApplication(UIViewRoot.java:1282)
    at com.sun.faces.lifecycle.InvokeApplicationPhase.execute(InvokeApplicationPhase.java:81)
    at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:101)
    at com.sun.faces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:198)
    at javax.faces.webapp.FacesServlet.service(FacesServlet.java:658)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:303)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
    at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:218)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:122)
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:505)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:169)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:103)
    at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:956)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:116)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:442)
    at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1082)
    at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:623)
    at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:318)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
    at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
    at java.lang.Thread.run(Unknown Source)
Caused by: java.lang.IllegalStateException: org.hibernate.TransientPropertyValueException: object references an unsaved transient instance - save the transient instance before flushing: br.com.bercalini.borracharia.modelo.Produto.marca -> br.com.bercalini.borracharia.modelo.Marca
    at org.hibernate.ejb.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1374)
    at org.hibernate.ejb.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1300)
    at org.hibernate.ejb.TransactionImpl.commit(TransactionImpl.java:80)
    ... 38 more
Caused by: org.hibernate.TransientPropertyValueException: object references an unsaved transient instance - save the transient instance before flushing: br.com.bercalini.borracharia.modelo.Produto.marca -> br.com.bercalini.borracharia.modelo.Marca
    at org.hibernate.engine.spi.CascadingAction$8.noCascade(CascadingAction.java:380)
    at org.hibernate.engine.internal.Cascade.cascade(Cascade.java:176)
    at org.hibernate.event.internal.AbstractFlushingEventListener.cascadeOnFlush(AbstractFlushingEventListener.java:160)
    at org.hibernate.event.internal.AbstractFlushingEventListener.prepareEntityFlushes(AbstractFlushingEventListener.java:151)
    at org.hibernate.event.internal.AbstractFlushingEventListener.flushEverythingToExecutions(AbstractFlushingEventListener.java:88)
    at org.hibernate.event.internal.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:51)
    at org.hibernate.internal.SessionImpl.flush(SessionImpl.java:1213)
    at org.hibernate.internal.SessionImpl.managedFlush(SessionImpl.java:402)
    at org.hibernate.engine.transaction.internal.jdbc.JdbcTransaction.beforeTransactionCommit(JdbcTransaction.java:101)
    at org.hibernate.engine.transaction.spi.AbstractTransactionImpl.commit(AbstractTransactionImpl.java:175)
    at org.hibernate.ejb.TransactionImpl.commit(TransactionImpl.java:75)
    ... 38 more

Pelo oque entendi o erro ocorreu porque não adicionei a minha marca, é apenas um chute, mais em geral os meus codigo fico assim.

public class ProdutoDao {

    public void adicionar(Produto produto) {
        EntityManager em = new JPAUtil().geEntityManager();
        em.getTransaction().begin();
        em.persist(produto);
        em.getTransaction().commit();
        em.close();
    }

Agora o meu bean

public void salvar() {
        if(produto.getCodigo() == null) {
            produto.setMarca(marca);
            new ProdutoDao().adicionar(produto);
            new MensagemUtil().mensagemInfo("Produto adicionado com sucesso");
        } else {
            new ProdutoDao().atualiza(produto);
            new MensagemUtil().mensagemInfo("Produto atualizado com sucesso");
        }
        this.produto = new Produto();
        this.marca = new Marca();
    }

o erro acho que está na hora de salvar né? oque que falto? :(

minhas classes java estao assim.

@Entity
@Table(name = "produto")
@NamedQueries({ @NamedQuery(name = "Produto.listarTodos", query = "Select p from Produto p") })
public class Produto implements Serializable {

    private static final long serialVersionUID = 1L;
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Column(name = "codigo")
    private Long codigo;
    @Column(name = "medida", length = 20, nullable = false)
    private String medida;
    @Column(name = "estado", length = 20, nullable = false)
    private String estado;
    @Column(name = "preco", scale = 2, precision = 5, nullable = false)
    private BigDecimal preco;
    @Column(name = "quantidadeResolagem")
    private Integer quantidadeResolagem;
    @Column(name = "ano")
    private Integer ano;
    @Column(name = "quantidade")
    private Integer quantidade;
    @OneToOne(fetch = FetchType.EAGER)
    @JoinColumn(name = "marca_codigo", referencedColumnName = "codigo")
    private Marca marca = new Marca();

    public Long getCodigo() {
        return codigo;
    }

    public void setCodigo(Long codigo) {
        this.codigo = codigo;
    }

    public String getMedida() {
        return medida;
    }

    public void setMedida(String medida) {
        this.medida = medida;
    }

    public String getEstado() {
        return estado;
    }

    public void setEstado(String estado) {
        this.estado = estado;
    }

    public BigDecimal getPreco() {
        return preco;
    }

    public void setPreco(BigDecimal preco) {
        this.preco = preco;
    }

    public Integer getQuantidadeResolagem() {
        return quantidadeResolagem;
    }

    public void setQuantidadeResolagem(Integer quantidadeResolagem) {
        this.quantidadeResolagem = quantidadeResolagem;
    }

    public Integer getAno() {
        return ano;
    }

    public void setAno(Integer ano) {
        this.ano = ano;
    }

    public Marca getMarca() {
        return marca;
    }

    public void setMarca(Marca marca) {
        this.marca = marca;
    }

    public Integer getQuantidade() {
        return quantidade;
    }

    public void setQuantidade(Integer quantidade) {
        this.quantidade = quantidade;
    }
}
@Entity
@Table(name = "marca")
@NamedQueries({
    @NamedQuery(name = "Marca.lista", query = "Select m from Marca m")
})

public class Marca implements Serializable{

    private static final long serialVersionUID = 1L;
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Column(name = "codigo")
    private Long codigo;

    @Column(name = "marca", length = 30, nullable = false)
    private String marca;

    public Long getCodigo() {
        return codigo;
    }

    public void setCodigo(Long codigo) {
        this.codigo = codigo;
    }

    public String getMarca() {
        return marca;
    }

    public void setMarca(String marca) {
        this.marca = marca;
    }
}
solução!

Alisson,

Esse erro que está dando agora é porque o objeto marca está transient, ou seja, não está gerenciado pelo contexto de persistência da JPA. Vamos deixar isso de lado, por enquanto... rsrs.

Quando você faz:

<p:selectOneMenu id="marca" value="#{produtoBean.marca.marca}"

você está setando no objeto do tipo Marca dentro do produtoBean. Agora, se você olhar a sua classe Produto, você vai ver que já tem um objeto do tipo Marca instanciado dentro dele.

@Entity
@Table(name = "produto")
@NamedQueries({ @NamedQuery(name = "Produto.listarTodos", query = "Select p from Produto p") })
public class Produto implements Serializable {
    // outros atributos
    @OneToOne(fetch = FetchType.EAGER)
    @JoinColumn(name = "marca_codigo", referencedColumnName = "codigo")
    private Marca marca = new Marca();

Isso significa, que você pode setar diretamente dentro do atributo marca do objeto produto dentro do seu produtoBean. Assim:

<p:selectOneMenu id="marca" value="#{produtoBean.produto.marca}"

Assim, você pode remover seu objeto marca de dentro de produtoBean (junto com get e set), pois lidará apenas com o objeto marca que está dentro do objeto Produto.

Dessa forma, quando você traz a lista de objetos marca para exibir na listagem, eles já estarão gerenciados (managed) pelo contexto de persistência da JPA, ou seja, não estarão mais transient. Daí, quando você for salvar seu objeto produto, o objeto marca dentro dele conterá um objeto managed (contrário de transient) e o produto será persistido e, na coluna marca_codigo dele, constará o id do registro correspondente à marca escolhida (o mesmo id da tabela marca).

Do jeito que está, talvez você precise de um conversor. Faz um teste e retorna.

Muito obrigado, precisou de conversor sim kkkk, mas acho que consigo arrumar. então o erro estava no meu produtoBean.marca.marca? kkkk eu nem reparei nessa possibilidade de ja tar instanciado o objeto marca. agora fico muito mais claro, e sim fiz umas aulas do curso que você me passou e dei uma olhada dos erros, para você poder atualizar um objeto e remover ele precisa estar merge kkk. E por exemplo se você tiver 2 entidades e adicionar só uma ou adicionar ele vai trazer o erro transient, mas quando você adiciona pelo persiste ele fica managed ai da para você fazer modificação e exclusão e buscar etc. Clareou muito depois dessas aulas, mas senti falta do joinCollun até as aulas que eu vi não vi nada relacionado com isso, mas ainda bem que sabia o basico do comando joinCollum kkkk. Obrigado mais uma vez kkk

Tem duas formas básicas de fazer isso: conversor ou pesquisar por id. Eu prefiro o conversor, acho mais "elegante". hehe.

A "menos elegante", útil caso você ainda não entenda ou não esteja usando CDI no seu projeto, é essa:

<p:selectOneMenu id="marca" value="#{produtoBean.produto.marca.id}"
                        required="true" requiredMessage="Marca obrigatória">
                        <f:selectItem itemValue="" itemLabel="Selecione a opção" />
                        <f:selectItems value="#{produtoBean.marcas}" var="marca"
                            itemLabel="#{marca.codigo}" itemValue="#{marca.marca}" />
                    </p:selectOneMenu>

E, no produtoBean:

public void salvar() {
    if(produto.getCodigo() == null) {
        // objeto m fica managed devido ao find
        Marca m = new MarcaDao().buscarPorId(this.produto.marca.id);
        // a atribuição funcionará com o m managed
        this.produto.marca = m;
        new ProdutoDao().adicionar(produto);
        new MensagemUtil().mensagemInfo("Produto adicionado com sucesso");
    } else {
        new ProdutoDao().atualiza(produto, marca);
        new MensagemUtil().mensagemInfo("Produto atualizado com sucesso");
    }
        this.produto = new Produto();
    }

O método buscarPorId(Integer id) usa o método find do EntityManager.

Se você preferir usar converter, o JSF não faz injeção de dependências em conversores, daí você pode usar uma biblioteca que provê esse recurso. Uso a omnifaces (http://central.maven.org/maven2/org/omnifaces/omnifaces/2.5.1/omnifaces-2.5.1.jar) que permite fazer a injeção de DAO em um converter. Essa injeção poderá ser feita diretamente a partir do JSF 2.3 (próxima versão), mas ainda não tem data definida para lançamento. É só colocar ela na sua pasta lib. Daí, seu conversor fica mais ou menos assim:

@FacesConverter("produtoConverter")
public class ProdutoConverter implements Converter{

    @Inject
    private ProdutoDao dao;

    @Override
    public Object getAsObject(FacesContext context, UIComponent componente, String valor) {
        try {
            return dao.buscarPorId(Long.parseLong(valor));
        } catch (RuntimeException e) {
            return null;
        }
    }

    @Override
    public String getAsString(FacesContext context, UIComponent component, Object objeto) {
        if (objeto != null && objeto instanceof Produto) {
            return ((Produto) objeto).getCodigo();
        } else {
            return "";
        }
    }
}

Testa aí os dois modos.

Abraço.

Obrigado Manoel. como sempre me ajudando muito. mais uma vez obrigado kkkk.

Beleza, Alisson!

Tópico solucionado?

Qualquer coisa, tô por aqui.

Abraço.

Abraço vlw