brunowc
Novembro 10, 2009, 3:42pm
#1
E ae pessoal, tudo certo, gostaria de saber se voces podem me ajudar,
Eu estou fazendo um projeto de controle de estoque, ´só que esta acontecendo o seguinte, existe o metodo armazenar, que serve pra atualizar os dados , só que quando eu armazeno, ele nao atualiza os dados, ele cria outro registro com os dados que eu alterei.
Pensei que fosse o GenerationType.SEQUENCE, mas comentei e mesmo assim continua do mesmo jeito …
segue em exemplo abaixo
tenho a classe produto
@Entity
public class Produto implements Serializable {
@Id
@GeneratedValue//(strategy = GenerationType.SEQUENCE)
@Column(name="id_produto")
private Long id;
@Column(name="nome_produto")
private String nome;
@Column(nullable=false)
private String modelo;
private double vlvenda;
private double vlcompra;
@Temporal(javax.persistence.TemporalType.DATE)
private Date data;
@ManyToOne(fetch = FetchType.EAGER)
@JoinColumn(name="id_categoria",
insertable=true, updatable=true)
@Fetch(FetchMode.JOIN)
@Cascade(CascadeType.ALL)
private Categoria categoria;
@ManyToOne(fetch = FetchType.EAGER)
@JoinColumn(name="id_fornecedor",
insertable=true, updatable=true)
@Fetch(FetchMode.JOIN)
@Cascade(CascadeType.ALL)
private Fornecedor fornecedor;
@ManyToOne(fetch = FetchType.EAGER)
@JoinColumn(name="id_marca",
insertable=true, updatable=true)
@Fetch(FetchMode.JOIN)
@Cascade(CascadeType.ALL)
private Marca marca;
@Column(unique=false, nullable=false)
private String status;
//getters e setters
O meu armazena da classe ProdutoLogic é esse
public void armazena(Produto produto) {
this.daoFactory.beginTransaction();
this.daoFactory.getProdutoDao().atualiza(produto);
this.daoFactory.commit();
}
O meu dao é segue o modelo da loja virtual
public void atualiza(T u) {
this.session.merge(u);
}
O que eu estou fazendo de errado ? como eu posso resolver este problema.
muito obrigado galera
Verifique se o Id do Produto não está nulo ao chamar o método armazenar
O objeto pode estar no modo de detached. Aí o merge vai persistir mesmo. Se for esse o caso, tenta fazer o seguinte (pra atualizar):
Objeto o = em.merge(o);
// Modificacoes no "o"
em.merge(o);
Você muda o estado dele e depois atualiza ele no banco.
brunowc
Novembro 11, 2009, 12:36am
#4
Entao ignacio83 , o id esta preenchido …
Andre Brito
Como eu insiro isto na logica do dao que eu estou usando … ?
brunowc
Novembro 11, 2009, 11:40pm
#5
pessoal, existe outra maneira de resolver este problema ?
No atualiza, tente fazer assim:
u = this.session.merge(u); // aqui é pra não inserir nada, só mudar o estado do objeto
this.session.merge(u);
brunowc
Novembro 17, 2009, 8:59pm
#7
E ae Andre, eu coloquei esse codigo no meu dao e mesmo assim continua criando um novo dado , e nao atualiza …
existe alguma outra maneira de resolver isso ?
lgweb
Novembro 18, 2009, 8:04am
#8
cara poste o codgo onde vc altera os dados do produto antes de atualizar pra mim dar uma olhada,pode ser ai que esta o problema.
thimor
Novembro 18, 2009, 10:04am
#9
vc esta usando JSF ? se for, o Bean deve estar no escopo de request. entao é so alterar no faces-config.xml para session. tb tive esse problema e foi isso.
brunowc
Novembro 18, 2009, 10:45am
#10
e ae igweb, o codigo ta ai embaixo
eu estou usando o vraptor na camada de controle, o metodo que eu estou usando pra atualizar é esse
public void armazena(Produto produto) {
this.daoFactory.beginTransaction();
this.daoFactory.getProdutoDao().atualiza(produto);
this.daoFactory.commit();
}
O form esta assim
<form action="produto.armazena.logic" method="post">
<fieldset>
<legend>Produtos</legend>
<input type="hidden" name="produto.id" value="${produto.id}">
<input type="hidden" name="produto.data" value="${produto.data}">
<table>
<tr>
<td>Nome do Produto:</td>
<td>Status:</td>
</tr>
<tr>
<td><input maxlength="25" size="35" name="produto.nome" value="${produto.nome}"></td>
<td><select name="produto.status" value="${produto.status}">
<option>ATIVO</option>
<option>INATIVO</option>
</select></td>
</tr>
<tr>
<td>Marca:</td>
<td>Modelo:</td>
</tr>
<tr>
<td><select name="produto.marca.id" id="marca">
<c:forEach var="marca" items="${listaMarcas}">
<option value="${marca.id}"
<c:if test="${produto.marca.id == marca.id}">selected="true"</c:if>>
<c:out value="${marca.nome}"/>
</option>
</c:forEach>
</select>
</td>
<td> <input maxlength="25" size="35" name="produto.modelo" value="${produto.modelo}"></td>
</tr>
<tr>
<td>Valor de Venda:</td>
<td>Valor de Compra:</td>
</tr>
<tr>
<td> <input maxlength="25" size="35" name="produto.vlvenda" value="${produto.vlvenda}"></td>
<td> <input maxlength="25" size="35" name="produto.vlcompra" value="${produto.vlcompra}"></td>
</tr>
<tr>
<td>Fornecedor</td>
</tr>
<tr>
<td><select name="produto.fornecedor.id" id="fornecedor">
<c:forEach var="fornecedor" items="${listaFornecedores}">
<option value="${fornecedor.id}"
<c:if test="${produto.fornecedor.id == fornecedor.id}">selected="true"</c:if>>
<c:out value="${fornecedor.nome}"/>
</option>
</c:forEach>
</select>
</td>
</tr>
<tr>
<td>Categoria:</td>
</tr>
<tr>
<td><select name="produto.categoria.id" id="categoria">
<c:forEach var="categoria" items="${listaCategorias}">
<option value="${categoria.id}"
<c:if test="${produto.categoria.id == categoria.id}">selected="true"</c:if>>
<c:out value="${categoria.nome}"/>
</option>
</c:forEach>
</select>
</td>
</td>
</tr>
</table>
<tr>
</tr>
<input type="submit" value="Cadastrar"/>
</fieldset>
</form>
brunowc
Novembro 18, 2009, 10:46am
#11
nao thimor, eu estou usando o vraptor…
lgweb
Novembro 18, 2009, 10:56am
#12
Quem chama o metodo public void armazena(Produto produto)
??
brunowc
Novembro 18, 2009, 3:35pm
#13
Entao funciona da seguinte maneira, tem a lista de produtos, onde tem um link que redireciona para o formulario para editar .
para editar dado, é esse o metodo
na pagina de listagem, tem esse link pra editar
<a href="produto.editar.logic?produto.id=${produto.id}">
public void editar(Produto produto) {
// carrega os dados no banco para edicao
this.produto = this.daoFactory.getProdutoDao().procura(produto.getId());
dai ele só manda pro jsp para ser editado, e o action do form é esse
<form action="produto.armazena.logic" method="post">
que no controlador é esse metodo
public void armazena(Produto produto) {
this.daoFactory.beginTransaction();
this.daoFactory.getProdutoDao().atualiza(produto);
this.daoFactory.commit();
}
que chama o metodo atualiza do dao
public void atualiza(T u) {
this.session.merge(u);
lgweb
Novembro 18, 2009, 4:08pm
#14
entaum cara , nunca utilizei VRaptor mas me parece que esta td correto com seus metodos,so se certifique que em nenhum lugar do seu codigo vc esteja usando um new Produto() ,pois esta e uma das causas destes tipos de erro, se vc esta com o id preenchido antes de salvar dentro do metodo armazena ele deveria somente atualizar ,verifique o valor do id antes de salvar e pegue o retorno do metodo merge, ele retorna um objeto,peque este objeto e verifique seu id so para confirmar, pode ser com print’s msm:
u=session.merge(u);
System.out.Println(" "+u.getId() );
brunowc
Novembro 22, 2009, 11:08am
#15
Huuuuuuuuuuum, esta dando um new produto sim…
neste trecho do codigo, na classe daofactory…
public class DaoFactory {
//fabrica de daos,
private final Session session;
private Transaction transaction;
public DaoFactory() {
session = HibernateUtil.getSession();
}
// abre transacao
public void beginTransaction() {
this.transaction = this.session.beginTransaction();
}
public void commit() {
this.transaction.commit();
this.transaction = null;
}
public boolean hasTransaction() {
return this.transaction != null;
}
public void rollback() {
this.transaction.rollback();
this.transaction = null;
}
public void close() {
this.session.close();
}
public UsuarioDao getUsuarioDao() {
return new UsuarioDao(this.session);
}
public ProdutoDao getProdutoDao() {
return new ProdutoDao(this.session);
}
entao ai que deve estar o problema … como eu poderia resolver isso?
soro
Novembro 23, 2009, 1:19pm
#16
O update não resolve?
session.update(objeto);
brunowc
Novembro 26, 2009, 6:25pm
#17
E ae pessoal , CONSEGUI RESOLVER O PROBLEMA !!!
eu peguei trauma desse metodo merge, eu estava atualizando na mesma pagina da edição, e nao estava fucionando com todos os toques que voces me deram, eu coloquei um SAVEORUPDATE no lugar do merge, e fiz carregar em outro formulario e FUNCIONOU !!!
valeu a ajuda de todos ,vcs sao 10!