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
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.