Oi pessoal!
Tenho uma galeria de fotos com 10 fotos, em cada uma existe um checkbox para marcar se é “avatar”, só pode haver uma foto como avatar. Ao subir uma foto marcando um checkbox Avatar a foto é salva no banco com um campo boolean “avatar”. Consigo carregar esse dado da seguinte forma:
O meu problema está sendo em ao clicar numa outra foto, teria que desmarcar o checkbox da anterior e enviar a id da nova foto por parâmetro e assim atualizar o avatar. Fiz o seguinte:
<script>
function setAvatar() {
var boxes = document.getElementByName("foto.avatar");
var foto = document.getElementByName("foto.avatar").value;
for(i=0;i<boxes.length;i++) {
if(boxes[i].checked) {
boxes.checked=false;
new Ajax.Request('atualizaAvatar',{
method: 'post',
parameters: foto,
onComplete: function(){
alert('O avatar foi alterado com sucesso!');
}
}
);
}
}
}
</script>
Pesquisando no Google achei o Prototype: http://www.prototypejs.org/learn/introduction-to-ajax
Estou seguindo o manual dele com outras dicas da internet, mas não está dando certo, ao marcar outra foto a anterior não é desmarcada e tb não passa nada por parâmetro pro Controller:
public void atualizaAvatar(Foto foto) {
fotoDAO.atualiza(foto);
}
Eu não sei como está sua entidade, mas eu faria diferente. Você tem N fotos, e uma delas será o avatar, correto?
Penso que ao invés da foto ter uma propriedade que diz se ela é avatar ou não, o correto é o Imovel saber quem é o avatar dele. Ou seja, mudando a entidade:
public class Imovel {
private List<Foto> fotos;
private Foto avatar;
}
Opa! Valeu Garcia!
Se eu entendi direito, ao fazer upload de uma foto e clicasse no checkbox para marcá-la como avatar o atributo avatar na classe Imovel guardaria a foto. Mas ai teria que alterar os métodos de upload no Controller e salvar no component né?
Abraço!
Não precisa ser exatamente no upload. Você pode fazer o upload normalmente e adicionar as fotos como você estava fazendo. A minha sugestão altera apenas a escolha do avatar, que ao invés de vocẽ colocar um isAvatar=true você indica no imovel qual a foto é um avatar.
Entendi a idéia, mas lá na JSP vou ter que continuar usando ajax pra mandar os dados da foto selecionada pro Controller e depois dar um update nos dados?
Guevara, para mim o botão de responder está aparecendo normalmente. Tente limpar o cache, ou algo assim.
Me tira uma dúvida, você tem um imóvel com uma lista de fotos, certo? E apenas uma dessas fotos pode ser o avatar do imovel, é isso? Na entidade Imovel você tem uma coleção de fotos?
Acho que então fica melhor você remover o atributo avatar da classe Foto. Após isso adicione o atributo avatar do tipo Foto na classe Imovel:
public class Imovel {
private List<Foto> fotos;
private Foto avatar;
}
Quase nada muda nas outras classes. Você continua normalmente adicionando e excluindo fotos. O que muda agora é na hora de você escolher quem é o avatar. Dessa forma nova você tem uma lista de fotos, então você marca qual será o avatar.
O Ajax eu não sei como fica porque conheço pouco o jquery. Você basicamente precisa apenas o valor da foto selecionada e também o id do imóvel. Aliás você nem precisa usar Ajax nisso, você pode fazer por formulário normal fazendo submit para o vraptor.
Oi Garcia!
Estou com um probleminha aqui na hora de chamar a aplicação. Fiz a alteração que vc sugeriu:
@OneToMany(targetEntity=Foto.class, mappedBy = "imovel",orphanRemoval=true)
public List<Foto> fotos;
private Foto avatar;
//getter and setter para avatar
E a stacktrace acusa:
root cause
org.hibernate.MappingException: Could not determine type for: br.com.imobiliaria.bean.Foto, at table: Imovel, for columns: [org.hibernate.mapping.Column(avatar)]
org.hibernate.mapping.SimpleValue.getType(SimpleValue.java:290)
org.hibernate.mapping.SimpleValue.isValid(SimpleValue.java:274)
org.hibernate.mapping.Property.isValid(Property.java:217)
org.hibernate.mapping.PersistentClass.validate(PersistentClass.java:464)
org.hibernate.mapping.RootClass.validate(RootClass.java:236)
org.hibernate.cfg.Configuration.validate(Configuration.java:1193)
org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1378)
org.hibernate.cfg.AnnotationConfiguration.buildSessionFactory(AnnotationConfiguration.java:954)
org.hibernate.ejb.Ejb3Configuration.buildEntityManagerFactory(Ejb3Configuration.java:883)
org.hibernate.ejb.HibernatePersistence.createEntityManagerFactory(HibernatePersistence.java:56)
javax.persistence.Persistence.createEntityManagerFactory(Persistence.java:48)
javax.persistence.Persistence.createEntityManagerFactory(Persistence.java:32)
br.com.caelum.vraptor.util.jpa.EntityManagerFactoryCreator.create(EntityManagerFactoryCreator.java:39)
sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
java.lang.reflect.Method.invoke(Method.java:597)
org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor$LifecycleElement.invoke(InitDestroyAnnotationBeanPostProcessor.java:340)
org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor$LifecycleMetadata.invokeInitMethods(InitDestroyAnnotationBeanPostProcessor.java:293)
org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor.postProcessBeforeInitialization(InitDestroyAnnotationBeanPostProcessor.java:130)
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyBeanPostProcessorsBeforeInitialization(AbstractAutowireCapableBeanFactory.java:394)
Não está aceitando o atributo do tipo Foto na classe Imovel, precisa anotar algo lá?
Abraço!
Oi pessoal…
Aproveitando o topico… alguém sabe como gero um formulario dinamico com o vraptor3… estava pensando em algo do tipo campos basicos como Nome, Endereço, Data de Nascimento, Sexo, e mais alguns serem fixos, e outros campos serem dinamicos no formulario. Como por exemplo buscar os campos dinamicamente no Mysql e gerar a tela de formulario. Estou querendo a cabeça aqui e não consigo. Apenas queria que facilitasse na hora de incluir mais um campo no formulario era só inserir mais uma linha numa tabela do mysql.
Alguem pode me ajudar?
Aguardo resposta.
Obrigado.
Leandro.
Oi pessoal!
Já entendi como fazer pra salvar esse avatar na tabela Imovel, mas estou com dúvidas na hora de implementar isso.
O problema é que apenas um imovel.setAvatar(avatar); no método de upload salva() não funciona, precisaria de um método de salvarAvatar() lá na DAO pra concluir o processo.
Algo do tipo:
public void salva(UploadedFile imagem, Imovel imovel, Foto foto, Foto avatar ) {
//codigo de upload
//ImovelDAO imovelDao = new ImovelDAO();
imovel.setAvatar(avatar); //este cara sozinho não salva o avatar na tabela imovel
//imovelDao.salvaAvatar(imovel, avatar);
//codigo para salvar a foto na tabela Foto
} catch (IOException e) {
throw new RuntimeException("Erro ao copiar imagem", e);
}
}
Precisaria de um metodo em ImovelDAO para salvar essa foto lá não?
Outra coisa, no meu componente Imagens, que é o código acima, a DAO injetada no construtor da classe não funciona, nem FotoDAO, nem ImovelDAO, preciso instanciar cada um deles no método salva(). O estranho é que é só na classe Imagens, que é um @Component. Preciso anotá-la com @RequestScoped que nem as DAO’s?
pra salvar um Imovel vc precisa salvar a Foto ANTES…
ou configurar o Cascade para PERSIST, aí ele faz automático…
qto ao problema dos daos, se a sua classe Imoveis é Session ou ApplicationScoped vc não consegue fazer um DAO, que é RequestScoped, funcionar…
isso pq assim que a Imoveis é criada, um DAO é criado e passado pra ele… mas o dao depende da requisição, então na primeira requisição a session (do hibernate) dele é fechada, e nas próximas ele vai ficar com um DAO inválido…
uma solução:
receba uma SessionFactory no construtor do Imoveis, e controle a sua sessão na mão, instanciando os DAOs na mão (mas uma vez só);
vc pode abrir a sessão já no início da classe (se o Imoveis for application scoped) e controlar as transações manualmente…
Oi Lucas!
Obrigado pelas dicas. Tentei seguir a dica do Garcia mas não dá, pq se eu salvo a foto, no imovel não salva nada, pois até então nada em Foto foi gravado. Estou pensando em criar uma classe Avatar só pra isso, ai a url do avatar não será salva na tabela Foto.
Tô quebrando a cabeça pra não criar código que cause dados duplicados de fotos no banco. =/
Acha a opção de criar uma classe Avatar especifica para isso uma opção ruim?
Abraço!!