Ajuda em estrutura de repetição para salvar no banco

Bom dia, tenho o método abaixo que recebe 2 Strings mas por ser um for e acho que é aí que estou errando, quando vou salvar no banco a segunda string não é salva.

Tenho que salvar isso:

fruta : maçã preço: 1.00
fruta: melão preço: 2.00

Mas quando vou no banco está assim:

fruta: maçã preço: 2.00
fruta: melão preço: 2.00

Poderiam me ajudar nessa lógica?

Aqui a lógica que estou usando:

List<Balcao> e = new ArrayList<>();
 for (String fruta: frutas) {
                Balcao d = new Balcao ();
                d.setNome(nome);    
                     for (String preco: precos) {                    
                     d.setPreco(preco);                  
              
                     }
             e.add(d);
        }

        for (Balcao b: balcoes) {
            try {
                this.daoFactory.getBalcaoDao().salva(b);
            } catch (Exception ex) {
                System.out.printl(ex)
            }
}

acontece por causa do segundo for,

voce tem duas ArrayLists?? uma com frutas e outra com preços?? porque? não era mais facil criar um objeto com esses dois atributos?

enfim, oque acontece é que o segundo for passa todo ArrayList precos e vai setando com o próximo valor, ou seja vai chegar no fim da lista e vai atribuir o ultimo valor.

não sei se entendi teu propósito, mas acho que é só tirar o segundo for, mas teria que controlar a posicão e com este tipo de for que você usou não sei se tem como fazer, vou te mostrar com o for antigo.

 for (int i = 0; i<frutas.size(); i++) {
                Balcao d = new Balcao ();
                d.setNome(nome);    
                d.setPreco(precos.get(i));                  
                e.add(d);
        }

@Sandro_Machado é que eu recebo esses valores de um formulário.

Tenho dois campos:
Campo fruta:

<input type="text" class="form-control" id="frutas" name="frutas[]" />

Campo preco:
<input type="text" class="form-control" id="precos" name="precos[]" />

Ai tenho um botão que ao ser clicado, cria dois novos campos acima.

Quando dou o submit do formulário, meu método que adiciona no banco, recebe essas duas Strings:

public void adiciona(List<String> frutas, List<String> precos) {

Ai dentro desse método, tem a lógica que passei no tópico… já inverti as ordens… e nada…continua do mesmo jeito, salva as duas frutas e o preço só de uma…

mas qual o vínculo da String fruta com a String preco?? cada fruta tem um preço?
ou uma fruta tem varios preços?

penso que você criar uma Classe FrutaVenda (nome sugerido), com atributos String fruta e String preco (melhor trabalhar com numeros, Double, BigDecimal, etc).

quando dá um submit, ele pega do formulário a String fruta e a String preco e instancia um nova classe FrutaVenda.

de posse dessa classe ai você adiciona na ArrayList Balcão que deve ter como Atributo uma FrutaVenda.

há outras formas também, ainda não ficou claro pra mim seu objetivo, Seu formulário tem vários Itens com fruta e preço né? e você vai clicando em um determinado botão que vai adicionando frutas e valores não é? quando invoca esse botão você captura a fruta e preco e monta a classe FrutaVenda, dai em diante é só fazer como anteriormente.

Entendi. Se for apenas 1 fruta e 1 valor… funciona na boa.

A questão é que meu formulário tem campos dinamicos usando o JQuery… então se só tem 1 fruta e 1 preço funciona perfeitamente… o problema é quando clico para criar novos campos…

Já testei com 10 frutas e com 10 preços… vai pro banco as dez frutas , porém o preço de cada uma fica com o valor da primeira fruta. Ai assim rsrsr ex:

Maça 1.00
Pera 1.00
Uva 1.00

Sendo que teria que estar cada uma com seu respectivo preço…:tired_face:

entendi e este código não funcionou?

 for (int i = 0; i<frutas.size(); i++) {
                Balcao d = new Balcao ();
                d.setNome(frutas.get(i));    
                d.setPreco(precos.get(i));                  
                e.add(d);
        }

@Sandro_Machado não … usando esse for que você postou, não consigo pegar os preços, pois estão em outra String…

public void adiciona(List<String> frutas, List<String> precos) { ...

Sua sugestão de outra classe, não achei viável no momento.

Um exemplo que vi agora pouco na net e é a mesma coisa foi o caso de uma pessoa que postou uma duvida sobre Advogado/Estagiario…

Na dúvida dele, ele tem o formulário de Advogado (dados nome etc) e a opção de cadastrar os nomes dos Estagiários que ficariam vinculados a este Advogado.
Nesse caso… então ele preenche o formulário do Advogado… nome x…etc e na opção Estagiario ele tem um javascript que cria os campos… ai clicando aparece o campo nome do estagiario e data de nascimento.
Se tiver outro estagiario, clica e cria outros dois campos… nome do estagiario e data de nascimento.

Então, eu segui a mesma lógica acima.

sim eu sei que estão em outra, por isso que ele pega o nome da fruta do ArrayList frutas e o preço do ArrayList precos.

            d.setNome(frutas.get(i));    
            d.setPreco(precos.get(i)); 

não entendo porque não daria certo.

Obrigado @Sandro_Machado… estou estudando isso.
Vou queimar mais neuronios pra ver se consigo .

@Sandro_Machado , seguindo suas dicas e outros posts neste forum… fiz assim:
Criei duas classes:
Balcao e Frutas:

@Entity
@Table(name = "tb_balcao")
public class Balcao implements Serializable {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Basic(optional = false)
    @Column(name = "balcao_cod")
    private Long cod;
    @Column(length = 150)
    private String nome;
    @OneToMany(mappedBy = "balcao", cascade = {CascadeType.ALL, CascadeType.REMOVE})
    private List<Fruta> frutas;
    //Construtor
    public Balcao() {
    }
    //Getter e Setter
....



@Entity
@Table(name = "tb_fruta")
public class Fruta implements Serializable {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Basic(optional = false)
    @Column(name = "fruta_cod")
    private Long cod;
    @Column(length = 150)
    private String nome;       
    private String preco;
    @ManyToOne
    private Balcao balcao;
    //Construtor
    public Fruta() {
    }
    //Getter e Setter
....

Montei o DAO e o Controller…

No meu controller eu tenho um método para adicionar Balcao e adiciona as frutas também, só pra lembrar que meu formulário tem os inputs para Balcão e um botão javascript para criar os campos das frutas.

:

@Post   
    public void adiciona(Balcao balcao, List<String> nomes, List<String> precos) {
        String retorno = "Operação realizada com sucesso.";
        try {            
            this.daoFactory.getBalcaoDao().salva(balcao);

        } catch (Exception ex) {
            System.out.println(ex);
        }
       
       insereListaFrutas(balcao, nomes, precos);       
        try {
            result.redirectTo(this).lista();
        } catch (ParseException ex) {
            Logger.getLogger(ClienteController.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

E por fim meu método insereListaFrutas…

private String insereListaFrutas(Balcao balcao, List<String> nomes, List<String> precos) {
        List<Frutas> frutas= new ArrayList<>();      
            for (String nome : nomes) {               
                d.setNome(nome);                
                d.setBalcao(balcao);
                frutas.add(d);

                for (String preco: precos) {
                    System.out.println(preco);
                    d.setPreco(preco);

                }

                for (Fruta a : frutas) {
                    try {
                        this.daoFactory.getFrutaDao().salva(a);
                    } catch (Exception ex) {
                        System.out.println(ex);
                    }

                }

            }       
    }

Então no meu formulário, preencho balcão, clico no botao JS aparecem dois inputs para nome e preco da fruta, clico de novo, outros dois inputs… preencho a outra fruta , se precisar clico de novo, preencho mais fruta e clico em salvar…

Vai tudo para o banco… só o bendito preco que está no for que fica sobrescrevendo…rsrsr

cara ainda não entendo porque você está colocando um for de precos dentro de um for de nomes.

é só usar o algoritmo com a correcao que te passei, impossível não dar certo.

        for (String nome : nomes) {               
            d.setNome(nome);                
            d.setBalcao(balcao);
            frutas.add(d);

            for (String preco: precos) {
                System.out.println(preco);
                d.setPreco(preco);// aqui está seu erro

            }

você vai setando todos os preços sobrescrevendo a cada iteração do for, por isso vai ficar sempre com o ultimo preco da lista.

@Sandro_Machado concordo com você. Também acho que isso está errado. Peguei algo no Fórum e tentei implementar na minha lógica.

Mudei o for e deixei desta maneira:

List<Fruta> frutas = new ArrayList<>();
for (int i = 0; i < nomes.size() && i < precos.size(); i++) {
            String nome = nomes.get(i), preco= precos.get(i);
            Fruta d = new Fruta();
            d.setNome(nome);           
            d.setPrecoo(preco);
            frutas.add(d);
        }
 for (Fruta a : frutas) {
                try {
                    this.daoFactory.getFrutaDao().salva(a);
                } catch (Exception ex) {
                    System.out.println(ex);
                }
            }

Desta maneira acima consegui fazer funcionar, porém a ordem no banco esta errada:
Deveria estar assim no banco:

Maçã  1.00
Pera   1.20

Porém tá invertido rsrsrsr:

Maçã  1.20
Pera   1.00

Pelo menos agora tá no caminho certo… teria alguma sugestão para corrigir isso?

kkkkk mano, esse foi o primeiro algoritmo que disse pra você implementar.

quanto a inversão de valores, pode ser na inserção dos valores na lista de frutas e precos, melhor debugar as inserções nessas duas listas.

Inspecionei os elementos do browser, no post as informações vão corretas.

Uma dúvida os campos do meu formulário estão assim:

<input type="text" class="form-control" id="nomes"  name="nomes[]" />
<input type="text" class="form-control" id="precos"  name="precos[]" />

E meu método no controller recebe como List nomes, List precos … está certo ou teria que ser String[] nomes, String[] precos ?

Percebi que isso ocorre sempre com o último elemento de List precos…
O browser envia:

id:frutas Banana    id:precos 5
id:frutas Uva         id:precos  3
id:frutas Morango  id:precos  8

E no banco é salvo

Banana  3
Uva       8
Morango 5

Fui no método e acrescentei antes do FOR :

System.out.println("Nomes: " +nomes);
System.out.println("Precos: " +precos);

E veja oque descobri… o método está recebendo as duas List ordenadas… agora vou tentar descobrir onde ocorre essa ordenação.

System.out:   Nomes: [Banana, Morango, Uva]
System.out:   Precos: [3, 5, 8]

Que bruxaria é essa rsrsrsrs: :fearful:

Boa tarde a todos. Problema resolvido.

Para quem estiver usando algum método parecido que recebe uma Lista via post no controller, depois de pesquisar bastante, descobri a solução: biblioteca IOGI .
Estou usando o VRaptor 3.5.1 com IOGI 0.9.2
Mantive a lib do Vraptor 3.5.1 em meu projeto, porém com a iogi 1.0.0

Aqui um post com um problema parecido, onde resolvi usar a solução:
http://respostas.guj.com.br/16536-problema-list-com-metodo-post--load

Tudo funcionando!