[RESOLVIDO] Checkbox selecionado

15 respostas
N

Olá!

Tenho um formulário jsp que apresenta uma lista de qualificações, estas são atribuídas ao Dentista no momento do cadastro do mesmo.
Essa lista é apresentada na forma de checkbox, onde o adm vai informar quais as qualificações do dentista. Além dessa lista, também são cadastrados outros dados.
Na minha regra de negócio, um Dentista possui um relacionamento muitos-pra-muitos com Procedimento e isso já está refletido no banco, através da associativa.

Observei em alguns fóruns sobre o assunto mas nenhuma das soluções propostas resolve o meu problema.

A listagem dos procedimentos (estes já cadastrados no BD):

Inicialmente eu estava listando desta forma:

<td>
       	<c:forEach items="${procedimentoList}" var="procedimento">
         	<input type="checkbox" value="${procedimento.id }"/>${procedimento.nome }</br>
	</c:forEach>
 </td>

Depois de algumas pesquisas, personalizei para a minha realidade e cheguei a este código:

<td><strong>Procedimentos que o dentista está apto a realizar</strong> </br>
       				<c:forEach items="${procedimentoList}" var="procedimento" varStatus="s">
       					<input type="checkbox" name="procedimentoList[${s.index}].id" value="${procedimento.id}"/>${procedimento.nome }</br>
				</c:forEach>
       			</td>

Mas mesmo assim ainda não deu certo. :roll:
Lembrando que no Controller eu estou recebendo List procedimentos.

Preciso que sejam gravados na tabela associativa Funcionario_Procedimento os ids do Dentista cadastrado e tbm dos procedimentos selecionados.

Desde já agradeço!!!

15 Respostas

Lagaffe

Nazaro_lc

Você poderia mostrar o controller.

Eu não percebi nenhum erro no jsp, porém eu costumo usar no input uma lista diferente da lista original. Ou seja se você está trazendo os dados na list: procedimentoList eu gravo os dados de retorno em dentista.procedimentos por exemplo. Neste caso no método do controller estarei recebendo um objeto Dentista. Não acho que isso cause o erro, mas me parece mais coerente.

Os dados estão chegando no controller? Ou o erro está na hora de gravar no banco de dados? Você esta usando hibernate?

Lucas_Cavalcanti

se vc recebe uma List procedimentos, vc deveria nomear o checkbox usando esse nome:

<input type="checkbox" name="procedimentos[${s.index}].id" value="${procedimento.id}"/>${procedimento.nome }

[]s

N

Lagaffe:
Nazaro_lc

Você poderia mostrar o controller.


O método no Controller:

public void adicionaD(Funcionario funcionario, List<Procedimento> procedimentos){
		dao.salvaD(funcionario, procedimentos);
		result.redirectTo(FuncionarioController.class).lista();
	}

no Dao:

public void salvaD(Funcionario funcionario,
			List<Procedimento> procedimentos) {
		Transaction tx = session.beginTransaction();
		session.save(funcionario);
		funcionario.setProcedimentos(procedimentos);
		tx.commit();

	}

Esclarecendoo 1:

Estou usando hibernate sim. Usando o método acima, eu salvo de boa no banco os dados da tabela Funcionario, não é retornado nenhum erro, porém o meu objetivo principal é o de informar quais procedimentos o dentista pode realizar. Preciso do id de Dentista e do id de Procedimento na associativa, os mesmos não estão sendo inseridos(Meu Problema).

Na minha classe Funcionario:

@ManyToMany(mappedBy="funcionarios")//lado fraco
	private List<Procedimento> procedimentos = new ArrayList<Procedimento>();

Na minha classe Procedimento:

@ManyToMany//lado forte
	@JoinTable(
		name="ta_funcionario_procedimento"
		, joinColumns={
			@JoinColumn(name="tb_procedimento_id_procedimento")
			}
		, inverseJoinColumns={
			@JoinColumn(name="tb_funcionario_id_funcionario")
			}
		)
	private List<Funcionario> funcionarios;

Esclarecendoo 2:
Estou chamando de Dentista só para facilitar a compreensão do negócio, o que existe mesmo é funcionario.

Lagaffe e Lucas, Valeu! Vou testar aqui as dicas de vcs.

N

Fiz essas alterações e os testes, mas não deu certo. :roll:

Alguém teria outras dicas?

Brigadss!

Lucas_Cavalcanti

os checkboxes tão com o name=“procedimentos[…]…”?
o nome do parametro da lógica é procedimentos?

tem algum checkbox checado?

N

Lucas Cavalcanti:
os checkboxes tão com o name=“procedimentos[…]…”?
o nome do parametro da lógica é procedimentos?

tem algum checkbox checado?

Os checkbox estão com os nomes nesse padrão mesmo. E o da lógica tá coerente.
Os checkbox estão checados.

Fiz um print de Procedimentos na lógica e percebi que os checkbox selecionados estão sendo recebidos(só não estou sabendo ver o conteúdo deles, pois está aparecendo “br.com.cadClient.entidades.Procedimento@1154…” para cada um dos checkbox selecionados, na quantidade do número de seleções).

:?: Para mostrar o conteúdo da lista eu uso print mesmo???

Agora acredito que o problema está acontecendo na hora de persistir, para que ele entenda que é pra "juntar " os procedimentos ao funcionario mandado tbm.

Aguardo.

Obrigadss.

Lucas_Cavalcanti

o problema é que é many-to-many e vc tah usando o lado fraco… daí qdo vc salva o funcionario, mesmo se vc coloque os procedimentos lá o hibernate vai ignorar…

não rola criar a classe intermediária (da sua tabela funcionario_procedimento)? pq daí na hora de salvar ia ficar bem melhor

N

Já tinha lido em algum post seu sobre a atualização, que deve ser a partir do lado forte.

Vou tentar com essa sugestão, de criar a funcionario_procedimento!

Mas se essa tabela intermediária não for criada, tem como eu fazer essa inserção? :?:

Valeww!

Lucas_Cavalcanti

se vc cria a classe que representa o funcionarioProcedimento, vc troca 1 many-to-many por dois many-to-one, daí é só salvar a funcionarioProcedimento q ele vai adicionar no funcionario e no procedimento

Lagaffe

Eu trabalho com ManyToMany em alguns casos. Tem funcionado bem.

Só que eu salvo dos dois lados. Não lembro bem porquê. Talvez porque não tenha funcionado de outro jeito.

O que complicou mais foram os casos de alterações.

A anotação ficou desta forma:

@ManyToMany(cascade = { CascadeType.PERSIST, CascadeType.MERGE }, fetch = FetchType.LAZY, mappedBy="usuarios", targetEntity = CentroResultado.class)
No outro lado (o forte) não tem o mappedBy

Lucas_Cavalcanti

Relacionamentos Many-to-many sempre tem algum significado envolvido, daí vc cria a tabela (e entidade) intermediárias com esse significado, pois ele mto provavelmente vai evoluir e ganhar alguns atributos e se vc colocou @ManyToMany vai ficar mto difícil mudar.

por exemplo

vc tem um Aluno many-to-many Escola, e depois vc descobriu que precisava guardar as notas desse aluno. Não faz sentido colocar nem em aluno nem na escola, deveria estar na tabela do meio.

Melhor seria ter feito Aluno many-to-one Matricula one-to-many Escola, daí é fácil colocar isso em matrícula.

meio forçado o exemplo, mas enfim

N

Então nesse caso eu não precisaria criar aquela tabela FuncionarioProcedimentoPK?
Mudaria os ids(iniciais ) para fks e os popularia manualmente?
:roll:

Lucas_Cavalcanti

não… tem que criar a tabela intermediária de qqer jeito. A diferença é que vc pode dar um nome melhor pra ela, por exemplo:

@Entity
public class GuiaProcedimento {
    @Id
    @GeneratedValue
    private Long id;

    @ManyToOne
    private Funcionario funcionario;

    @ManyToOne
    private Procedimento procedimento;

    //outros campos, se necessário
}

assim o hibernate cria as fks corretamente pra vc

N

Aêe Pessoal! Valeu pela força!!

Lucas, usei sua dica e criei uma classe intermediária.

No Dao ficou da seguinte forma!

public void salvaD(Funcionario funcionario, List<Procedimento> procedimentos) {
		for(Procedimento p : procedimentos){
		Transaction tx = session.beginTransaction();
		FuncionarioProcedimento fpr = new FuncionarioProcedimento();
		session.save(funcionario);

			fpr.setFuncionario(funcionario);
			fpr.setProcedimento(p);
			session.save(fpr);
			
			tx.commit();

		}

Não sei se o código está no padrão das boas práticas mas resultou no que eu queria: uma tabela com os ids dos procedimentos selecionados no checkbox e do respectivo funcionario.
:smiley:

Valewws!

Lucas_Cavalcanti

uma coisa que eu faria nesse código é receber o funcionario e o procedimento no construtor do FuncionarioProcedimento:

FuncionarioProcedimento fpr = new FuncionarioProcedimento(funcionario, p); 
session.save(funcionario);
session.save(fpr);

daí tiraria os setters da classe, e deixaria a classe mais encapsulada. Pro hibernate não te chingar vc precisa criar um construtor sem argumentos, mas ele pode ser privado.

Criado 2 de dezembro de 2010
Ultima resposta 4 de dez. de 2010
Respostas 15
Participantes 3