[RESOLVIDO]Componente não é salvo na sessão[RESOLVIDO]

29 respostas
101574

Galera,
Como já falei aqui antes, sou iniciante no vraptor.
Ele é excelente para me deixar de cabelo branco.rssrs.
Vamos, lá.
Pelo que eu entendi, e so anotar a classe com @SessionScoped. Para ele ser salvo na sessão, e ser único.
Estou fazendo uma loja virtual. Utilizei a apostila FJ-28.
Mas na apostila, eles não salvam no banco o carrinho de compras.
E eu estou tentando salvar ele no banco de dados.
A principio, fiz uma outra classe chamei-a de orçamento.
Fiz o relacionamento, com itens.
Quando a pessoal clicar em Novo Orçamento, eu crio no banco de dados um orçamento.
Conforme a pessoa vai escolhendo os itens do orçamento, ela vai adicionando e já vai salvando esses itens também no banco.
So que, eu preciso enviar junto com o novo item adicionando o codigo do produto e o codigo do orçamento.
O codigo do produto, está indo certinho, já o codigo do orçamento não vai.

Olha como ficou minha classe Orcamento.java - ela está no meu modelo.

@Entity
@Component
@SessionScoped
public class Orcamento {

//váriaveis
@Id @GeneratedValue
private Long id;
private String numero;
private double total;
private double desconto;
private double frete;

/Relacionaomento com orcamentoItens
	@OneToMany(mappedBy = "orcamento",targetEntity= Itens.class,
	fetch = FetchType.LAZY, cascade = CascadeType.ALL)
	private List <Itens> itens;
//Metodos get e set

Minha classe Itens.java - Também está no meu modelo.

@Entity
public class Itens {
	@Id @GeneratedValue
	private Long id;
	private double quantidade;
			
	//Relacionamento com Produtos
		@ManyToOne
		@JoinColumn(name="produto_id")
		private Produto produto;
		//Relacionaomento com orcamento
		@ManyToOne(cascade=CascadeType.PERSIST)
		@JoinColumn(name="orcamento_id")
		private Orcamento orcamento;
		//Métodos Set e get

Tenho o controller de cada uma, que salva no banco de dados.

Na minha lista de produtos, e adicionei um botão adicionar a cada produto.
Ficou assim.

lista.jsp - esta em jsp/produtos

<!-- Adicionando o produto ao orçamento -->
<td>
<form action="<c:url value="/itens"/>" method="POST">
<input type="hidden" name="itens.produto.id"
value="${produto.id}"/>
<input class="qtde" name="itens.quantidade" value="1"/>
<input type="hidden" name="itens.orcamento.id"
//Orçamento
value="${orcamento.id}"/>
<button type="submit">Adicionar</button>
</form>
</td>

Teoricamente, era pra quando eu clicar em adicionar.
Ele salva o item, com o id do produto e do orçamento.
Como eu falei, do produto ele salva corretamente, já do orçamento ele fala que não encontrou a referência.

br.com.caelum.vraptor.InterceptionException: exception raised, check root cause for details: org.hibernate.TransientObjectException: object references an unsaved transient instance - save the transient instance before flushing: br.com.caelum.goodbuy.modelo.Orcamento

Se eu alterar e colocar o id do orçamento no campo ‘value’ ele salva corretamente.
Já tentei colocar o orçamento no interceptor, para aparecer em todas as páginas, também não rolou.
Podem me ajudar?

Valeu Galera!

29 Respostas

Rafael_Guerreiro

Como ele é @SessionScoped, você não precisa passar ele para a view o tempo todo, o VRaptor já faz isso para você. :wink:

Agora, ao invés de pegar o ID do orçamento na view e depois receber na action, que tal se você simplesmente recebesse o Orçamento no construtor do seu controller?

Assim você evita que alguém mude o ID do orçamento na view e você usa uma feature muito boa que é a DI.

101574

A ideia é excelente.
Seria ótimo. Pena que eu não consegui fazer.

Olha o que eu fiz.

@Resource
public class ItensController {
	private final ItensDAO dao;
	private final Result result;
	private final Orcamento orcamento;
	public ItensController(ItensDAO dao,Result result, Orcamento orcamento) {
	this.dao = dao;
	this.result = result;
	this.orcamento = orcamento;
	}

	@Post("/itens")
	public void adiciona(Itens itens) {
	//O que eu faço aqui, para ele passar o id do meu orçamento??
	dao.salva(itens);
	result.redirectTo(this).lista();
	}

Agora, como eu faço pra passar o orcamento na linha ai encima?
Sei que não “fazem” código pra gente.
Teria que criar um metodo em Orcamento ou Item?

Rafael_Guerreiro

Eu não sei COMO você quer salvar. Mas esse orcamento será salvo aonde? Dentro de item?
Então faça algo nesse sentido:

item.setOrcamento(this.orcamento);
101574

Brother,
Eu tenho duas classes.
Dois controllers.
O que eu preciso e quando eu for salvar um novo item, pegar o id do orçamento e salvar em orcamento_id da tabela itens.
So isso.

Rafael_Guerreiro

Tentou fazer aquilo que eu falei?

101574
Olha como ficou.
@Resource
public class ItensController {
	private final ItensDAO dao;
	private final Result result;
	private final Orcamento orcamento;
	public ItensController(ItensDAO dao,Result result, Orcamento orcamento) {
	this.dao = dao;
	this.result = result;
	this.orcamento = orcamento;
	}

	@Post("/itens")
	public void adiciona(Itens itens, Orcamento orcamento) {
	//O que eu faço aqui, para ele passar o id do meu orçamento??
	itens.setOrcamento(this.orcamento);  
	dao.salva(itens);
	result.redirectTo(this).lista();
	}
Minha lista de produtos.
<!-- Adicionando o produto ao orçamento -->
<td>
<form action="<c:url value="/itens"/>" method="POST">
<input type="hidden" name="itens.produto.id"
value="${produto.id}"/>
<input class="qtde" name="itens.quantidade" value="1"/>
<!-- <input type="hidden" name="itens.orcamento.id"
value="${orcamento.id}"/>
-->
<button type="submit">Adicionar</button>
</form>
</td>
101574

Mano, descula minha burrice.rsrs.

Rafael_Guerreiro

Ta, mas e ai? O que aconteceu? Deu certo?

Deu erro? Explodiu?

101574

O meu brother,
Explodir, explodiu.
Foda que não funcionou.
Continua com o mesmo erro.

101574

Quais são os passos para salvar um dado na sessão?
Eu só preciso salvar o orcamento.id na sessão, e que ele seja único.
Dessa forma. Já está bom.

Lucas_Cavalcanti
br.com.caelum.vraptor.InterceptionException: exception raised, check root cause for details: org.hibernate.TransientObjectException: object references an unsaved transient instance - save the transient instance before flushing: br.com.caelum.goodbuy.modelo.Orcamento

esse erro quer dizer que vc tentou salvar uma entidade XXX, que tem um Orcamento dentro dela e esse orçamento não está salvo…

é só salvar o orçamento antes de salvar a XXX.

101574

Pois é meu brother.
Eu to tentando colocar o orçamento na sessão.
E com isso, passar o id dele para salvar em itens.

Lucas_Cavalcanti

salve o orçamento então no começo de tudo…

ou só acumule todos os itens na memória e salve no banco só ao final do processo.

101574

Estou salvando o orçamento primeiro.
Faço assim.
Inicio a aplicação.
Entro com usuario e senha.
Crio um novo orçamento.
E depois eu mando ele salvar o item.

Ta ai, como eu faço pra após eu criar o orçamento, colocar ele na sessão automáticamente.

Lembrando que ele está anotado com.

@Component
@SessionScoped
Lucas_Cavalcanti

ele é uma entidade que está anotada com @Component?

não faça isso… se o orçamento é uma @Entity, faça:

@Component
@SessionScoped
public class OrcamentoEmProgresso {
     private Orcamento orcamento;
     // getters/setters
}

assim vc separa o que tá no banco do que está na sessão

101574

Não, é necessário component.
O que eu preciso e salvar na sessão.
Pq ele não salva na sessão?
Tem que fazer algo mais.
TIpo, quando eu entrar na minha aplicação eu quero adicionar orçamento.
Colocar ele na seção
Escolher os meus produtos, e bimba adicionar o meu item com o id do meu orçamento.

101574

Olha o que eu fiz.

Meu orçamento,ficu assim.

@Entity
public class Orcamento {

Minha classe OrcamentoEmProgresso.

@Component  
@SessionScoped  
public class OrcamentoEmProgresso {
	private Orcamento orcamento;
//Metodos set e get

Agora, como eu faço pra colocar ele na sessão?
Pq quando eu crio um novo usuario, eu preciso fazer login para colocar ele na sessão.
Eu vou clicar em orcamento/novo
Vou criar um novo orçamento. Vou colocar os dados necessários.
Agora, eu quero, inserir um item, passando o id_orcamento que está na sessão.
Consigo fazer isso como?

Lucas_Cavalcanti

receba o OrcamentoEmProgresso no construtor que vc vai mexer com isso e mexa com o orçamento que está la dentro…
tipo:

// orcamento/novo
Orcamento orcamento = // cria e salva no banco
orcamentoEmProgresso.setOrcamento(orcamento);

// novo item
Item item = // o que veio da requisição
item.setOrcamento(orcamentoEmProgresso.getOrcamento());

se quiser pode mover algumas dessas lógicas pra dentro do OrcamentoEmProgresso.

101574

Beleza!
Entendi. Mas não sei implementar no Controller do Vraptor.
Tem como você me ajudar?

@Get("/orcamento/novo")
	@Restrito
	public void formulario(Orcamento orcamento) {
//O eclipse acusa que 
	OrcamentoEmProgresso.setOrcamento(orcamento);

	}
Precisa implementar aqui também?
@Post("/orcamento")
	@Restrito
	public void adiciona(final Orcamento orcamento) {
		dao.salva(orcamento);
		result.redirectTo(this).lista();
	}
101574

Não tem nada a ver com o problema.
Mas, tem certificação Vraptor?
Como eu aprendo de verdade Vraptor?

Lucas_Cavalcanti

OrcamentoEmProgresso, não é pra usar a classe…

receba uma instancia desse cara no construtor e use a instancia pra setar…

dá uma olhada na apostila do VRaptor, ela ensina a parte básica toda, inclusive sessão

http://www.caelum.com.br/curso/fj-28

101574
@Resource
public class OrcamentoController {
	private final OrcamentoDAO dao;
	private final Result result;
	private final OrcamentoEmProgresso orcamentoEmProgresso;

	public OrcamentoController(OrcamentoDAO dao,Result result,
			OrcamentoEmProgresso orcamentoEmProgresso) {
	this.dao = dao;
	this.result = result;
	this.orcamentoEmProgresso = orcamentoEmProgresso;
	}
	@Get("/orcamento")
	@Restrito
	public List<Orcamento> lista() {
	return dao.listaTudo();
	 }
	@Post("/orcamento")
	@Restrito
	public void adiciona(final Orcamento orcamento, OrcamentoEmProgresso orcamentoEmProgresso) {
		orcamentoEmProgresso.setOrcamento(orcamento);
		dao.salva(orcamento);
		result.redirectTo(this).lista();
	}
Lucas_Cavalcanti

funcionou assim?

101574

Funcionou!

Cara, muito obrigado!
Você não tem noção o quanto me ajudou.
Mas ta correto o codigo?
To achando meio estranho.rsrs.
Vou continuar implementando, qualquer coisa. Volto aqui.
Para finalizar. Para utilizar o codigo na minha view.
Ficou assim.

<h3>${orcamentoEmProgresso.orcamento.id}</h3>

Está ótimo!

-> Em, sobre o vraptor.
Existe algum tipo de certifcação?
O curso sobre Vraptor na Caelum, e qual?
Valeu.

Lucas_Cavalcanti

Não tem certificação, mas tem um curso online e a apostila:

apostila: http://www.caelum.com.br/curso/fj-28-vraptor-hibernate-ajax/
curso online: http://www.caelum.com.br/curso/online/vraptor/

101574

Valeu!
A apostila, eu fiz ela todinha.rsrs.
To pensando em refaze-la toda.
E vou ver o curso online.
Não tem esse curso presencial ne?

101574

Você já fez esse curso?
O que você aprende na prática?
Valeu.

Lucas_Cavalcanti

Sim, eu já fiz esse curso, no sentido de prepará-lo :wink:

é uma introdução ao vraptor, explicando as partes direitinho.

o curso presencial geralmente não tem demanda o suficiente pra fechar uma turma, por isso a gente deixa só a apostila. O VRaptor é facil o suficiente pra aprender :wink:

Qualquer dúvida pode postar aqui! =)

101574

Poww cara!
Desculpa ae.rsrsrs.
Valeu. Estou fazendo contato para comprar o pacote 6(seis) meses.
Obrigadão mesmo pela ajuda.

Criado 18 de setembro de 2012
Ultima resposta 18 de set. de 2012
Respostas 29
Participantes 3