Vraptor + problema chato

11 respostas
marcio89

Pessoal, bom dia.
To usando o Vraptor já tem um tempo mas não consigo mais aguentar isso daqui:

/** <code>Result</code> do VRaptor */
	private final Result result;

	/** <code>Validator</code> do VRaptor. */
	@SuppressWarnings("unused")
	private Validator validator;

	/** Usuário logado. */
	@SuppressWarnings("unused")
	private final UserInfo userInfo;

	/** DAO da entidade <code>Evaluation</code> */
	private final EvolutionDAO evolutionDAO;

	/** DAO da entidade <code>UtiBed</code> */
	private UtiBedDAO utiBedDAO;

	/** DAO da entidade <code>Patient</code> */
	private PatientDAO patientDAO;

	/** DAO da entidade <code>GlasgowSelect</code> */
	private GlasgowSelectDAO glasgowSelectDAO;

	/** DAO da entidade <code>ApacheSelect</code> */
	ApacheSelectDAO apacheSelectDAO;

	/** DAO da entidade <code>MedicalDeviceDAO</code> */
	private MedicalDeviceDAO medicalDeviceDAO;

	/** DAO da entidade <code>MedicineDAO</code> */
	private MedicineDAO medicineDAO;

	private DoctorDAO doctorDAO;
	
	private EvolutionBS evolutionBS;
	
	/** Construtor padrão do Controlador. */
	public EvolutionController(Result result, Validator validator, UserInfo userInfo, EvolutionDAO evolutionDAO, UtiBedDAO utiBedDAO, PatientDAO patientDAO, DoctorDAO doctorDAO,
			MedicalDeviceDAO medicalDeviceDAO, MedicineDAO medicineDAO) {
		this.result = result;
		this.validator = validator;
		this.userInfo = userInfo;
		this.evolutionDAO = evolutionDAO;
		this.utiBedDAO = utiBedDAO;
		this.patientDAO = patientDAO;
		this.doctorDAO = doctorDAO;
		this.medicalDeviceDAO = medicalDeviceDAO;
		this.medicineDAO = medicineDAO;
	}

Olha o dando de DAO que eu tenho que passar no controller pra poder salvar um registro no banco.
Como resolvo isso ?

11 Respostas

marcio89

Aproveitando, qual é a melhor formar de fazer um relacionamento entre a entidade filha com a pai.
To tendo que fazer um loop nas entidades filhas colocando a entidade pai em cada uma.

Valeu.

Lucas_Cavalcanti

o seu controller receber muitos daos é um forte sinal de que essa classe esteja fazendo coisas demais…

agrupe as funcionalidades parecidas em outras classes (sejam elas controllers, ou outro componente), daí resolve esse problema.

sobre a segunda dúvida, se essas filhas estão vindo da tela, vc pode já setar o pai nelas:

<input type="hidden" name="filhas[${index}].pai.id" value="${pai.id}"/>
Rafael_Guerreiro

Eu gostaria de aproveitar o gancho e tirar uma dúvida:
É legal eu criar um converter do VRaptor para uma classe minha, exemplo:

public class Cidade {
   private long id;
   private String nome;
// getters e setters
}

Essa classe é uma entidade e eu tenho um DAO que consegue buscar pelo ID da cidade.
Na minha jsp eu tenho o seguinte caso:

&lt;select name="cidade"&gt;
   &lt;option value="1"&gt;São Paulo&lt;/option&gt;
   &lt;option value="2"&gt; Rio de Janeiro&lt;/option&gt;
&lt;/select&gt;

No meu controller, eu tenho uma action que recebe a cidade, e não um long:

@Get("/path/xpto")
public void pegaCidade(Cidade c){
// faz algo.
}

Para que isso funcione, eu preciso cadastrar um converter para Cidade:

@Convert(Cidade.class)
public class CidadeConverter implements Converter&lt;Cidade&gt; {
   private CidadeDAO dao;
   public Cidade (CidadeDAO dao){
      this.dao = dao;
   }

   public Cidade convert(String value, Class&lt;? extends Cidade&gt; type,
			ResourceBundle bundle){
      return dao.get(Long.parseLong(value));
   }
}

Minha dúvida é: isso é uma boa prática? Se não, o que eu devo fazer ao invés disso?

Lucas_Cavalcanti

se isso vai facilitar o código, não vejo pq não fazer :wink:

só lembre de usar as buscas lazy (tipo o em.getReference ou session.load) assim vc pode fazer isso pros relacionamentos tb…

e já existe a anotação @Load que faz exatamente isso :wink:

Rafael_Guerreiro

Mas a anotação @Load retorna um erro quando o objeto não é encontrado. Correto?

E se eu quisesse receber null?

O @Load funciona para os atributos de uma classe minha?
Exemplo:

public class Estado {
   private long id;
   private String uf;
   private String nome;
   private Cidade cidade;
// getters e setters
}
@Get("/abcde/")
public void fazAlgo(@Load Estado estado) {// Assim, se eu tiver um estado.cidade e passando somente o ID da cidade, ela será populada também?
// faz algo
}
Lucas_Cavalcanti

nao… o load eh soh pra propria classe mesmo…

o @Load retorna 404 se o cara nao eh encontrado, nao?

Rafael_Guerreiro

Existe alguma forma de sobrescrever o @Load?
Assim eu faria ele retornar null, e não retornar o 404… às vezes a gente pode querer que o objeto venha nulo…

Lucas_Cavalcanti

é que esse @Load foi feito pra esse tipo de método:

@Get("/produto/{produto.id}")
public void mostra(@Load Produto produto) {...}

então se o produto não existe tem que dar 404.

mas vc pode usar essa mesma idéia e criar seu próprio @Load… ou usar o seu converter mesmo.

marcio89

Lucas vlw pelas respostas! Outra coisa… E se o id for gerado automaticamente na hora do save da entidade pai? Vai funcionar?

Lucas_Cavalcanti

vc vai adicionar o pai e os filhos ao mesmo tempo?

nesse caso essa estratégia não vai funcionar, e vc vai ter que fazer o loop mesmo, ou mudar o mapeamento pros dois lados do relacionamento serem fortes (cuidado com isso)…

talvez tenha que usar cascade=PERSIST tb

P

Marcio89, vc pode trocar todos esses DAOs por uma classe que cria os DAOs.

Criado 20 de julho de 2012
Ultima resposta 23 de jul. de 2012
Respostas 11
Participantes 4