Tenho um relacionamento MAnyToMany, com Setor tem muitos Procedimentos e Procedimento tem muitos Setores.
A minha dúvida é, adiciono na lista os procedimentos ao setor, por enquanto via MySQL, na mão, consigo listar na aplicação e implementei o Edite e excluir, mas quando estou excluindo, por exemplo um procedimento de um Setor que tem por exemplo 4 procedimento, ele esta excluindo todos procedimentos e o Setor junto. Qual CascadeType seria ou alem do cascade tenho que implementar diferente meu excluir?
Amigo, isto é um erro classifico de relacionamento em OO, você precisa se perguntar sempre, um setor tem um procedimento ou um procedimento tem um setor, acho que a resposta para seu caso é um setor tem um procedimento, então os procedimentos não precisam conhecer os setores que os possuem e o cascade propaga todas as ações que você implementa aquele objeto.
//um setor tem vários procedimentos@OneToMany(cascade=CascadeType.ALL,mappedBy=Setor.class)privateList<Procedimento>procedimentos=newArrayList<Procedimento>();//vários procedimentos de um setor@ManyToOneprivateList<Setor>setores=newArrayList<Setor>();
Assim o jpa vai criar a terceira tabela automaticamente não precisando fazer um joincolumn e também a propagação só será realizada quando você excluir um setor e não mais quando excluir um procedimento. Também você poderá ter um mesmo procedimento em outros setores.
R
Rafael_Blum
Sim… faz sentido mesmo. E com relação a questão de excluir depois o procedimento, por que, assim terei dois casos: Tenho a tela que lista os procedimento, e se nesta tela eu excluir ele direto, como fica se algum Setor tiver ele em sua lista? E também, se na tela de Setor tenho todos Setores listado, e clico em um setor X e em outra tela listo os procedimentos que tenho nele, se eu excluir aquele procedimento, tenho que criar um metodo especifico para tirar ele da lista do setor X, isso (Sem excluir aquele procedimento do sistema, mas só da lista do X)?
V
Villagram1 like
Rafael, quando você tem uma lista distribuída você deve criar triggers para impedir a exclusão no caso de existirem múltiplos usos, mas no código que escrevi para você ao excluir um procedimento qualquer ele sumiria de todos os setores. Fazemos essas listas para evitar cadastros com descrições repetitivas, caso queria registrar procedimentos e depois atribui-los sem nenhum vinculo você precisa criar um cadastro de procedimentos e replicar os mesmos em outra tabela, então ao excluir do cadastro você não afetaria os registros dos setores e vice-versa.
R
Rafael_Blum1 like
Sim, entendi.
Vou implementar aqui e comento. Muito obrigado.
Assim que der certo, confirmar registro a resposta, pode ser?
R
Rafael_Blum
Ola, Villagram
o mappedBy = Setor.class gera um erro:
Type mismatch: cannot convert from Class to String
O que pode ser?
Não deveria ser:
//um setor tem vários procedimentos@OneToMany(cascade=CascadeType.ALL,mappedBy="setores")privateList<Procedimento>procedimentos=newArrayList<Procedimento>();//vários procedimentos de um setor@ManyToOneprivateList<Setor>setores=newArrayList<Setor>();
V
Villagram
@Rafael_Blum O mappedBy server para indicar a classe que é “dona” do relacionamento e que vai ter um comportamento de parecido com o de uma super class, essa exceção é gerada por que você está colocando um parâmetro errado, o que deve ser informado é a classe, não uma String…
Coloque o nome da classe seguido de “.class”.
Exemplo: mappedBy = Setor.class
Normalmente eu coloco o nome da classe onde o relacionamento foi mapeado.
R
Rafael_Blum
Mas eu fiz como falou…
Coloquei a classe, mas fica com erro…
Mantenho o @ManyToMany que a principo atualmente esta dando certo ou tentamos essa solução que falou?
R
Rafael_Blum
O que estou fazendo hoje:::::
Deixei @ManyToMany do dois lados como no inicio.
Não estou gerando o combo. Quando estou criando o Setor ele fica na listagem Table e clico no setor assim jogando para uma tela de detalhes daquele setor em especifico e ali tem uma lista de procedimentos em dataTable que vou ADD clicando no procedimento que quero.
Não sei se mudar para como sugeriu abaixo, se ficaria melhor? Se ficar mudamos.
//um setor tem vários procedimentos@OneToMany(cascade=CascadeType.ALL,mappedBy=Setor.class)privateList<Procedimento>procedimentos=newArrayList<Procedimento>();//vários procedimentos de um setor@ManyToOneprivateList<Setor>setores=newArrayList<Setor>();
V
Villagram
@Rafael_Blum amigo desculpe-me, li o que escrevi e realmente eu estava errado, me confundi , use o targetEntity = Setor.class e retire o mappedBy, você só precisa dele caso tenha classes de chave composta, caso contrário o jpa usa o atributo marcado com ‘@Id’.
Posso te passar os arquivos por email? Será que consegue ver o que é?
Tipo os pacotes (model, controllers, bensViews, etc)
E conseguindo, postamos a solução aqui.
V
Villagram
não utilizo o eclipse, modelar o projeto inteiro novamente daria muito trabalho.
V
Villagram
O erro que você mandou diz que você está fazendo referência a uma entidade desconhecida, a classe pode não estar anotada com ‘@Entity’, a classe pode não estar declarado no arquivo de configuração, o modelamento do relacionamento pode estar incorreto nas classes em questões(existem várias regras que devem ser seguidas).
Cara o hibernate está reclamando por que você está colocando as anotações diretamente nos atributos, como uma boa prática sempre colocamos as anotações nos getters para não ocorrer quebra de encapsulamento.
Este é outro erro, agora ele está dizendo que não consegue determinar o tipo para java.util.list na tabela setor para a coluna procedimento.
Agora para saber o por que preciso ver as classes modificadas.
V
Villagram
Tente fazer o drop das tabelas e deixe o hibernate recria-las sozinho
R
Rafael_Blum
Eu tinha dropado todas tabelas de setor, procedimento… e dai ele criou tudo certinho, OK.
Entrou no sistema… tela inicial OK
Clico no botão de entrar na tela de cadastro do procedimento e gera erro.
V
Villagram
Tenta não criar as listas dentro do objeto, tira o new ArrayList.
R
Rafael_Blum
Vou tentar…
Amanhã ajusto e tento e lhe falo brow… to caindo de sono
R
Rafael_Blum
Utilizando o select * from procedimento no MySQL, procedimento fica com uma coluna_id, é normal?
R
Rafael_Blum
E outra coisa,
Fiz desta mesma forma que me falou para um outro relacionamento em meu projeto que é PEDIDO tem muito PRODUTOS (só pedido enxerga os produto).
Confirma tmb, utilizar assim?
@Rafael_Blum Desculpe a demora em responder, mas como não me marcou não apareceu a notificação para mim.
Explica um pouco melhor, não entendi o problema.
Muitas vezes em um relacionamento de tabelas principalmente no caso de pedidos e produtos é normal o pedido conhecer seus produtos mas os produtos não sabem de qual pedido são, caso queira que o produto guarde o número de id do pedido basta adicionar a anotação JoinColumn ao seu atributo.
R
Rafael_Blum
Fiz assim e funcionou.
Agora queria saber, cada procedimento fica com uma coluna de setor_id? Ela é obrigatória, porque? É que tenho uma tela que crio o procedimento e nela não quero vincular ao setor, somente quando eu criar o setor e adicionando proced.
E percebi que as vezes temos problemas com a questão do fetch = FetchType.EAGER. Por que queremos listar e tal… vou ter problemas em criar o setor e adicionar o procedimentos?
V
Villagram1 like
@Rafael_Blum nesse tipo de relacionamento o banco cria uma terceira tabela, os procedimentos tem de ser vinculados ao setor pelo id, mas quando vc criar um setor você pode ou não informar um procedimento e o mesmo vale pro lado inverso. Tudo fica a critério da sua imaginação na hora de programar.
R
Rafael_Blum
Na realidade, Villagram, estou utilizando esta mesma dica que me falou na relação de pedido e produto, esta correto da mesma forma né?