[Logo] Neo Framework Forum
  [Search] Busca   [Recent Topics] Tópicos Recentes   [Members]  Lista de Usuários   [Groups] De volta para a página principal 
[Register] Registrar / 
[Login] Entrar 
Many-to-many  XML
Índice dos Fóruns -> Dúvidas Ir para a página: 1, 2 Próximo 
Autor Mensagem
robmsjr
MultiAction

Membro desde: 26/06/2007 19:30:49
Mensagens: 88
Offline

Estou tentando fazer um mapeamento many-to-many no NEO e estou com algumas dificuldades (Tentei descobrir como fazer o many-to-many usando o one-to-many como rogel falou mas n consegui);

Segue aqui os mapeamentos e o erro encontrado:

Classe Funcionalidade
Code:
 @ManyToMany(targetEntity=Licenca.class,cascade={CascadeType.PERSIST, CascadeType.MERGE}
 	)
 	@JoinTable(
 	name="funcionalidade_licenca",
 	joinColumns={@JoinColumn(name="idfuncionalidade")},
 	inverseJoinColumns={@JoinColumn(name="idlicenca")}
 	)
 	public List<Licenca> getLicencas() {
 		return licencas;
 	}
 


Classe Licenca
Code:
 @ManyToMany(
 	cascade={CascadeType.PERSIST, CascadeType.MERGE},
 	mappedBy="licencas",
 	targetEntity=Funcionalidade.class
 	)	
 	public List<Funcionalidade> getFuncionalidades() {
 		return funcionalidades;
 	}
 	
 


Erro:
Code:
  ERROR org.neo.exemplo.controller.FuncionalidadeCrud - Erro ao invocar método doEntrada da classe org.neo.exemplo.controller.FuncionalidadeCrud. Redirecionando para input: entrada
 br.com.linkcom.neo.controller.crud.CrudException: Não foi possível usar o saveOrUpdateManaged(String) para org.neo.exemplo.bean.Funcionalidade! Possíveis causas: A os itens do collection não possuem referencia para o pai, O path estava incorreto. O path leva a uma coleção que não tem classe persistente
 	at br.com.linkcom.neo.controller.crud.CrudController.doSalvar(CrudController.java:273)
 


DAO:
Code:
 @Override
 	public void saveOrUpdate(Funcionalidade bean) {
 		  new SaveOrUpdateStrategy(getHibernateTemplate(), bean)
 		          .saveEntity()
 		          .saveOrUpdateManaged("licencas")
 		          .execute();
 		 }
 
 	@Override
 	public void updateSaveOrUpdate(SaveOrUpdateStrategy save) {
 		save.saveOrUpdateManaged("licencas");
 	}


valeu pela ajuda,

abraços;
pedro.goncalves
Equipe
[Avatar]
Membro desde: 17/04/2007 16:12:20
Mensagens: 539
Localização: Belo Horizonte - MG
Offline

Aqui tem a resposta da sua dúvida: http://www.neoframework.org/forum/posts/list/15/96.page

Pedro Gonçalves
http://pedrogoncalves.com.br
[Email] [WWW] [MSN]
robmsjr
MultiAction

Membro desde: 26/06/2007 19:30:49
Mensagens: 88
Offline

Ali ele explica a relação one-to-many... no caso meu problema está em uma many-to-many; mas estou tentando descobrir aqui.
pedro.goncalves
Equipe
[Avatar]
Membro desde: 17/04/2007 16:12:20
Mensagens: 539
Localização: Belo Horizonte - MG
Offline

De acordo com o Rógel, O pessoal do hibernate não recomenda o ManyToMany.. de uma olhada neste tópico que tem a explicação.. e como usar o oneToMany que vai funcionar da mesma maneira..

té!

Pedro Gonçalves
http://pedrogoncalves.com.br
[Email] [WWW] [MSN]
rogel.garcia
Xiita

Membro desde: 17/04/2007 16:35:03
Mensagens: 275
Offline

Quando é utilizado ManytoMany.. vc nao precisa especificar no QueryBuilder que deseja salvar a coleçao... ela já será salva automaticamente..

Esse é um dos problemas de utilizar manytomany... vc tem que escolher.. ou salva a colecao sempre.. ou nunca salva.. nao tem como especificar se deseja salvar via query..

por isso o ManytoOne - OneToMany é recomendavel
robmsjr
MultiAction

Membro desde: 26/06/2007 19:30:49
Mensagens: 88
Offline

Ok.
Agora, para utilizar o ManytoOne - OneToMany, eu tenho que criar a classe da tabela de ligação não é isso?

E fazendo isso eu não posso mais colocar no jsp
<t:property name="licencas"/>, porque no meu bean eu vou ter uma lista de FuncionalidadeLicenca que não vai carregar os dados da licenca sozinha.

Nesse caso eu teria então que passar uma lista de licenca para o jsp e depois pegar no crud com request e setar manualmente na minha lista de funcionalidadeLicenca?

Ou teria outra maneira?

rogel.garcia
Xiita

Membro desde: 17/04/2007 16:35:03
Mensagens: 275
Offline

Faz uma propriedade licencas @Transient no seu bean.

Aí vc poderá utilizar no JSP

<t:property name="licencas"/>

Você terá que copiar a lista licencas para a lista de funcionalideLicenca e vice versa... (vc pode copiar no próprio getter e setter de licencas do bean)

Utilizar ManyToMany não é proibido, nem errado.. É apenas não recomendável.

Você deve analizar de acordo com a sua aplicação o que for mais fácil.
rogel.garcia
Xiita

Membro desde: 17/04/2007 16:35:03
Mensagens: 275
Offline

Code:
 class Funcionalidade {
     List<FuncionalidadeLicenca> funcionalidadesLicencas;
 
      ... outras propriedades.. getters e setters...
     
     @Transient // o transient informa ao hibernate para nao manipular essa propriedade
     public List<Licenca> getLicencas(){
         List<Licenca> licencas = new ArrayList<Licenca>();
         for(FuncionalidadeLicenca fl: funcionalidadesLicencas){
              licencas.add(fl.getLicenca());
         }
         return licencas
     }
 
     public void setLicencas(List<Licenca> licencas){ 
         funcionalidadesLicencas = new ArrayList<FuncionalidadeLicenca>();
         for(Licenca licenca: licencas){
             FuncionalidadeLicenca fl = new FuncionalidadeLicenca();
             fl.setFuncionalidade(this);
             fl.setLicenca(licenca);
             funcionalidadesLicencas.add(fl);
         }
     }
 }
 
robmsjr
MultiAction

Membro desde: 26/06/2007 19:30:49
Mensagens: 88
Offline

Entendi a ideia... Vou dar uma testada para ver como fica.
robmsjr
MultiAction

Membro desde: 26/06/2007 19:30:49
Mensagens: 88
Offline

Fiz do modo que você sugeriu e dei uma testada rapida... está dando esse erro aqui:

Code:
 org.springframework.beans.InvalidPropertyException: Invalid property 'licencas' of bean class [org.neo.exemplo.bean.Funcionalidade]: Getter for property 'licencas' threw exception; nested exception is java.lang.reflect.InvocationTargetException: null
 java.lang.reflect.InvocationTargetException
 


valeu pela ajuda, de qlq modo estarei olhando melhor amanhã de manhã;
rogel.garcia
Xiita

Membro desde: 17/04/2007 16:35:03
Mensagens: 275
Offline

Deu Null pointer nessa linha


for(FuncionalidadeLicenca fl: funcionalidadesLicencas){

vc deve testar se a funcionalidadesLicencas é diferente de null antes do for


if(funcionalidadesLicencas != null)
for(FuncionalidadeLicenca fl: funcionalidadesLicencas){
robmsjr
MultiAction

Membro desde: 26/06/2007 19:30:49
Mensagens: 88
Offline

Beleza. Era isso mesmo e agora ta funcionando legal.
valeu mesmo.
robmsjr
MultiAction

Membro desde: 26/06/2007 19:30:49
Mensagens: 88
Offline

Estou com uma duvida em uma outra tela, segue código:

Modulo:

Code:
 @OneToMany(mappedBy="modulo")
 	public List<Funcionalidade> getFuncionalidades() {
 		return funcionalidades;
 	}
 


Funcionalidade:
Code:
 @ManyToOne(fetch=FetchType.LAZY)
 	@JoinColumn(name="idmodulo")
 	public Modulo getModulo() {
 		return modulo;
 	}
 


ModuloDAO

Code:
 @Override
 	public void saveOrUpdate(Modulo bean) {
 		  new SaveOrUpdateStrategy(getHibernateTemplate(), bean)
 		          .saveEntity()
 		          .saveOrUpdateManaged("funcionalidades")
 		          .execute();
 		 }
 
 	@Override
 	public void updateSaveOrUpdate(SaveOrUpdateStrategy save) {
 		save.saveOrUpdateManaged("funcionalidades");
 	}
 


Problema:
Na view de modulo, ele exibe inicialmente tudo ok, porém quando vai salvar os dados, ele só preenche na tabela de funcionalidade os campos idfuncionalidade e idmodulo.

Eu resolvi dando um load nas funcionalidades da lista mas queria saber se tinha um modo mais facil.

abraços
rogel.garcia
Xiita

Membro desde: 17/04/2007 16:35:03
Mensagens: 275
Offline

No DAO para salvar o atributo licencas

Ou vc faz:

Code:
  @Override
  public void saveOrUpdate(Funcionalidade bean) {
    new SaveOrUpdateStrategy(getHibernateTemplate(), bean)
            .saveEntity()
            .saveOrUpdateManaged("licencas")
            .execute();
   }
 


ou vc faz:

Code:
  @Override
  public void updateSaveOrUpdate(SaveOrUpdateStrategy save) {
       save.saveOrUpdateManaged("licencas");
  }
 


Se vc utilizar a primeira opção a segunda opção nem será chamada. Se desejar veja o código do saveOrUpdate no GenericDAO para entender melhor..

Não entendi bem a sua dúvida.
Mas se vc tem os campos em determinado bean

- nome
- telefone
- id

E no JSP vc só coloca os campos nome e id
O campo telefone será perdido na hora de salvar o bean. A menos que vc carregue o bean antes.
Para vc não perder as informações vc deve colocar por exemplo, um campo hidden com o valor que não deseja perder. Ex:

<t:property name="telefone" type="hidden"/>
robmsjr
MultiAction

Membro desde: 26/06/2007 19:30:49
Mensagens: 88
Offline

Vou fazer o load então para resolver o problema, valeu.

Agora estou com uma outra duvida meio besta...

Eu quero fazer um select com as descrições ("Física", "juridica") e valores ("F", "J") para setar em um campo String tipoPessoa;

Como eu faria isso, sem colocar o select direto em html e sim carregando de uma constante no meu bean?

EDIT: Eu fiz um improviso aqui com uma list mas não sei se é o ideal
 
Índice dos Fóruns -> Dúvidas Ir para a página: 1, 2 Próximo 
Ir para:   
Powered by JForum 2.1.7 © JForum Team