[RESOLVIDO]Registro de uma Venda

Seguinte pessoal, eu possuo uma classe de Venda, na qual possuia uma lista de ItensVendidos, esses itens vendidos possuem Produto e quantidade

até ae tudo bem, eu estava usando um OneToMany e many to one porem me deparei com a seguinte situação, para registrar uma venda preciso dos itens vendidos e para registrar os itens vendidos, precisa do codigo da venda, (ou seja na hora da inserção ambos sao novos registros) eu pensei no metodo em primeiro criar a venda e depois inserir esses itens vendidos nessa venda, porem ocorre um problema, quando eu faço um save de Venda, ele gera um codigo e tudo bunitinho, mais logo abaixo eu tenho que fazer a inserção dos itensVendidos, passando o codigo dessa venda, e nao tem como eu conseguir esse codigo sendo que eu acabei de fazer um save, ou seja ele gerou um codigo agora. porem a unica solução que encontrei é fazer o seguinte,

session.save(venda)

Consulta para encontrar o ultimo registro da venda para retornar essa venda

e fazer ItemVenda.setVenda(venda)

mais nao sei se essa é a melhor forma de fazer, até pq para pequenas empresas isso funciona mais quando a demanda aumenta, pode ocorrer de registrarem duas vendas paralelamente e essas inserções darem problema.

Ué… o hibernate nao coordena isto não… por exemplo:

Venda venda = new Venda(); //nova venda, nao inserida no bd

venda.setItemVenda(new ItemVenda()); //adicionando novo item de venda

vendaDao.save(venda); //insere o venda, e suas dependencias.. no caso ItemVenda

?

Venda nao possui 1 item de venda, possui 1 lista de itens de venda. em venda eu tenho um


@OneToMany(MappedBy="Venda")
private List<ItemVenda>

Em item venda eu possui um:

@ManyToOne(name="CodigoVenda", referencedColumn="codigo")
private Venda venda;

o problema é: só posso inserir um itemvenda.venda() se eu possuir um CODIGO de Venda, ou seja uma venda já registrada no banco, pq antes de fazer um save(venda) o codigo dele está vazio até pq quem faz isso pra mim é o proprio hibernate.

Ou seja basicamente eu teria que fazer o seguinte.


VendaDAO.save(venda) 
  
Venda venda = VendaDAO.carregarUltimo() //Efetuar uma busca no banco para me retornar o ultimo objeto inserido em venda e carregar em uma classe venda

//e percorrer a lista de ItensVendidos e setar essa ultima venda no itemdeVenda, até pq ele só seta se possuir um codigo que é exatamente o que vai fazer referencia
for(Itemvenda u : listadeitens) {  
u.setVenda(venda);
}

O problema todinho é pq tanto a venda e os itensdevenda sao NOVOS, ou seja tenho que efetuar o registro e ao mesmo tempo pegar esse ultimo registro e já inserir nesses novos itens, pq essa relação entre OneToMany e ManyToOne é bidirecional e OBRIGATORIAMENTE precisa dos CODIGOS.

eu acho que se vc colocar um CascadeType.ALL e fizer:

Venda venda = new Venda(); //sem ID sem nada

List<ItemVenda> itensVenda = new ArrayList<ItemVenda>();
itensVenda.add(new ItemVenda()); //imagine um item aqui
itensVenda.add(new ItemVenda()); //outro aqui
itensVenda.add(new ItemVenda()); //e mais um.. tudo sem ID

//e depois fizier um:
vendaDao.save(venda);

ele vai gerenciar isto tudo pra vc.
Na verdade, no save do dao que estou utilizando o save retorna a propria entidade:

@Override
	public T salvar(T entity) {
		Transaction transaction = null;

		try {
			transaction = this.getSession().beginTransaction();
			this.getSession().saveOrUpdate(entity);
			transaction.commit();
		} catch (ConstraintViolationException cve) {
			throw new DAOException(cve);
		} catch (Exception ex) {
			throw new DAOException(AbstractBaseDAOImpl.UNKNOWN_ERROR, ex);
		} finally {
			if (transaction != null && transaction.isActive()) {
				transaction.rollback();
			}
		}

		return entity;
	}

abraços

bem, você chegou num ponto bacana, só que ontem que vou REGISTRAR meus ITENSVenda no banco?
que no caso seria o itemvendaDAO.save(item) ?

Por favor faz o que eu te falei como ‘teste’?

Do jeito que estou pensando não precisa de um itemVendaDAO…
Coloca la cascadetype all…
e depois tenta salvar só o VENDA

*(Crie uma classe de testes… nao joga isso na sua logica com interface e tudo não ta)
hehe
abraços

Opa d34d, testei, nao funcionou, porem já resolvi, eu fiz o seguinte, removi o OneToMany de vendas e deixei somente o manytoone de ItemVenda e fiz o seguinte.

fiz o vendaDAO.save(venda).

venda = vendaDAO.ultimaVenda() //aqui ele faz uma busca e me retorna a ultima venda e carrega o objeto nessa venda.

for( Itemvenda u : lista) {
u.setVenda(venda) //aqui a venda já possuirá um codigo. e por isso conseguirá referenciar.
itemDAO.save(u);
}

Andei analisando e tive que fazer isso pq na venda é uma excessao pois tanto a venda quanto os itens que estão sendo vendidos, estão sendo criado no mesmo momento, então tive que remover a lista de venda e dentro de item venda possui um codigo que referencia todos os itens de uma determinada venda.

Mesmo assim, obrigado pela ajuda, graças a isso tive essa ideia. obrigado.

Desculpa, mas eu não acredito que vc tenha testado direitinho…
Em todas as outras aplicações que tem relacionamento eu faço assim
e funcionam, pq contigo nao funcionaria?

mas tudo bem… que bom que resolveu o problema.
Pode editar o tópico e mudar o título para [resolvido] ?
obrigado cara
abração

PS: utilize a tag code ao postar códigos :slight_smile:

Desculpa, mas eu não acredito que vc tenha testado direitinho…
Em todas as outras aplicações que tem relacionamento eu faço assim
e funcionam, pq contigo nao funcionaria?

R: testei sim brother, sinceramente testei, o problema é que tenho que fazer esses 2 procedimentos em paralelo e da erro de chave estrangeira quando possui essa lista de itens vendidos na class venda.

mas tudo bem… que bom que resolveu o problema.
Pode editar o tópico e mudar o título para [resolvido] ?
obrigado cara
abração

R: ok, colocarei.