Dúvidas Herança com VRaptor [RESOLVIDO]

20 respostas
worldsoft

Boa noite a todos,

Estou com o seguinte problema:

public class Pessoa{...}
public class PessoaFisica extends Pessoa{...}
public class PessoaJuridica extends Pessoa{...}

Pelo que eu pesquisei e li nos resultados do google, o vraptor não tem como saber qual classe específica ele terá que implementar…
Bom gostaria de saber como posso resolver esse impasse, sendo que somente saberei o tipo de pessoa que terei que implementar, quando o usuário selecionar o tipo especifico.

Desde já Agradeço a todos.

20 Respostas

bronx

Você poderia dar um exemplo prático? Não entendi o problema…=/

Lucas_Cavalcanti

um dos jeitos:

crie um converter pra Pessoa, que a partir de um valor decide qual é a implementação.

e pra passar o valor vc usa na request:

nomeDoParametro = valor

ex:

public void metodo(Pessoa pessoa) {...}

//param: pessoa=PessoaFisica
worldsoft

Um exemplo prático seria +/- assim:

Tenho um formulário de cadastro de pessoas (nome, endereço, telefone, e-mail, bler, bler...) Mais pessoa não exite certo?, então tenho que determinar qual o tipo de pessoa que terei que instanciar, "Pessoa Física" - (Data de nascimento, cfp, rg, bler, bler,...) ou "Pessoa Juridica" - (Nome Fantasia, CNPJ, IE, bler, bler, ...) Mais como uso injeção de dependência do VRaptor, no meu formulário eu não trabalho direto com “PF” ou “PJ”, pois somente saberei que tipo de pessoa é, assim que o usuário selecionar, dessa forma, precisava saber como poderia instanciar “PF” ou “PJ” em tempo de execução e usando Injeção de dependência.

Espero que tenha entendido!

Obrigado.

worldsoft
Lucas Cavalcanti:
um dos jeitos:

crie um converter pra Pessoa, que a partir de um valor decide qual é a implementação.

e pra passar o valor vc usa na request:

nomeDoParametro = valor

ex:

public void metodo(Pessoa pessoa) {...}

//param: pessoa=PessoaFisica

Lucas,

Pelo o que eu entendi, teria q criar um parametro para espedificar qual o tipo de pessoa que terei q implementar certo?
Mais e os parâmetros específicos de cada tipo que está no formulário, terei que passar cada valor por um parametro e pega-lo na request?

Obrigado.

Lucas_Cavalcanti

os específicos não precisa passar separado não… uma vez que o VRaptor instanciar o tipo certo, ele vai conseguir popular os campos diferentes…

[]'s

worldsoft

Lucas Cavalcanti:
os específicos não precisa passar separado não… uma vez que o VRaptor instanciar o tipo certo, ele vai conseguir popular os campos diferentes…

[]'s

Lucas desculpa minha ignorância mais ainda não entendi como fazer…

tipo eu tenho +/- a seguinte jsp:

<fmt:message key="user.form.label.typePerson"/>	
	<select id="typePerson" size="1" name="user.person.typePerson">
		<option value="PHYSICAL"><fmt:message key="user.form.label.typePerson.physical"/></option>
		<option value="JURIDICAL"><fmt:message key="user.form.label.typePerson.juridical"/></option>
	</select>
	
	<!-- Pessoa fisica -->
	<fmt:message key="user.form.label.cpf"/>	
	<input type="text" name="cpf"/><br>		
	
	<fmt:message key="user.form.label.dateBirth"/>
	<input type="text" name="dateBirth"/><br>			
	
        <!-- Pessoa Juridica -->
	<fmt:message key="user.form.label.cnpj"/>
	<input type="text" name="cnpj"/><br>			
							
	<fmt:message key="user.form.label.name"/>
	<input type="text" name="user.person.name"/><br>
	
	<fmt:message key="user.form.label.email"/>
	<input type="text" name="user.person.email"/><br>	
	
	<fmt:message key="user.form.label.telephone"/>
	<input type="text" name="user.person.telephone"/><br>

Quando eu executar o submit desse form, na minha lógica eu uso o convert para trasnformar o objeto pessoa eum um tipo específico segundo o parâmetro:

"user.person.typePerson"

Mais como o vraptor irá saber após executar esse convert que o cpf é do objeto q eu acabei de converter?
No meu form eu uso o que para atribuir cpf a pessoa?

Obrigado.

Lucas_Cavalcanti

ao invés de fazer o input:

<input type="text" name="cpf"/><br>

vc faz:

<input type="text" name="user.person.cpf"/><br>

e o nome do select não seria user.person.typePerson, e sim user.person pro vraptor chamar o converter.

se user.person for uma pessoa física, ele vai conseguir setar o cpf.

worldsoft

Lucas sua ajuda está sendo de grande ajuda,

Tava pensando que teria que criar esse convert na mão…

Mais relendo a documentação do VRaptor vi como posso fazer esse converter ser chamado automaticamente pelo VRaptor.

http://vraptor.caelum.com.br/documentacao/conversores/

Bom, muito obrigado pela ajuda.

worldsoft

Lucas…

Tem como informar que a conversão terá que ser executada antes do VRaptor começar a adicionar as informações no objeto, pois está acontecendo o seguinte:
Quando dou o submit o vraptor está adicionando os valores nas propriedades do objeto “Person”, depois ele entra no convert dessa forma ele adquire uma instancia especializada de “Person”, assim os valores que foram adicionados em suas propriedades são perdidos com essa nova instancia de “Person”.

Lucas_Cavalcanti

isso é um bug que já foi corrigido, mas a gente não lançou ainda…

se quiser corrigir também, copie essa classe pro seu projeto:

e anote-a com @Component

worldsoft

Lucas,

Funcionou Belezinha.
Mais uma vez obrigado.

worldsoft

Lucas só mais uma dúvida…

Quando eu for carregar esses dados na view, a JSTL saberá como tratar esse caso.

Tipo no formulário de edição tenho que carregar o cpf de um PersonPhysical, e ai eu utilizo ${user.person.cpf}?

Lucas_Cavalcanti

geralmente ele se vira bem…

no máximo vc vai ter que fazer um if pra só colocar isso se for do tipo PersonPhysical.

worldsoft

Lucas Cavalcanti:
geralmente ele se vira bem…

no máximo vc vai ter que fazer um if pra só colocar isso se for do tipo PersonPhysical.

Te perguntei isso porque a seguinte mensagem está sendo apresentada.

javax.el.PropertyNotFoundException: Property 'cpf' not found on type br.com.bfree.model.Person_$$_javassist_6

Tendo em vista que no meu mapeamento das classes o objeto “Person” está com fetch.LAZY, será esse o problema?

Lucas_Cavalcanti

sim, esse é um dos problemas… como tá lazy, o hibernate vai criar um proxy de Person, e não da classe filha… se fizer sentido esse relacionamento como EAGER, tenta isso

worldsoft

Com EAGER funciona certinho, foi a primeira coisa que pensei, mais ache que tivesse um outro jeito…

Bom se não tiver, fica assim mesmo…

Obrigado novamente.

Lucas_Cavalcanti

isso já não tem mto a ver com o VRaptor, é particularidade do hibernate mesmo…

mas pensa bem… se você está se relacionando com Person, você não deveria chamar person.getCpf(), pq não existe esse método em Person…

provavelmente esse código de mostrar o cpf está no lugar errado.

o que a gente faz é algo como ter um getCadastro(), que na pessoa física retorna o cpf, e na jurídica retorna o cnpj.

Dica: tradução de Pessoa física não é PersonPhysical nem de longe. O conceito de Pessoa física e jurídica só existe aqui… na verdade abstrair isso pra uma Pessoa não faz muito sentido. Particularmente não gosto de traduzir termos brasileiros pro inglês. Isso dificulta o entendimento pelos outros programadores. Ex. o equivalente em inglês pra boleto, nota fiscal, prestação é muito diferente, e quase ninguém conhece.

worldsoft

Lucas Cavalcanti:
isso já não tem mto a ver com o VRaptor, é particularidade do hibernate mesmo…

Já havia imagina.

Concordo…

Só por curiosidade e aprendizado, se eu tiver mais parâmetros específicos para cada especialização? Tipo: Inscrição estadual, Nome Fantasia , e mais um monte de códigos que uma pessoa jurídica tem aqui no Brasil, como ficaria?


Dica: tradução de Pessoa física não é PersonPhysical nem de longe. O conceito de Pessoa física e jurídica só existe aqui… na verdade abstrair isso pra uma Pessoa não faz muito sentido. Particularmente não gosto de traduzir termos brasileiros pro inglês. Isso dificulta o entendimento pelos outros programadores. Ex. o equivalente em inglês pra boleto, nota fiscal, prestação é muito diferente, e quase ninguém conhece.

Obrigado pela dica, tomarei mais cuidado da próxima vez.

Lucas_Cavalcanti

se você tem um formulário pra cadastrar pessoa física, ele só tem que aparecer com pessoas físicas…

o jeito que eu faria é via ajax:

<....>página bonita</...>
<div id="pessoaForm"></div>

e logo que a página carregar, num código javascript usando jquery:

$("#pessoaForm").load("/pessoa/${pessoa.id}");

e essa url é a de um controller que cospe o formulário de pessoa já com o tipo certo

worldsoft

Entendi…

Bom desculpa pela amolação e obrigado pelas respostas…

Criado 21 de dezembro de 2011
Ultima resposta 23 de dez. de 2011
Respostas 20
Participantes 3