Hibernate + Imagem

9 respostas
P

Pessoal,

Preciso gravar uma imagem no Banco de Dados usando Hibernate. Procurei por aí (inclusive aqui no GUJ) e todas as soluções dizem para, ao invés de Image, utilizar Byte[]. Por exemplo, em vez de:

public class Cliente {

     ...
     private Image foto;
     ...
     ...
     ...

     public Image getFoto() {
          return foto;
     }

     public void setFoto(Image foto) {
          this.foto = foto;
     }

     ...
     ...

}

eu usaria:

public class Cliente {

     ...
     private byte[] foto;
     ...
     ...
     ...

     public byte[] getFoto() {
          return foto;
     }

     public void setFoto(byte[] foto) {
          this.foto = foto;
     }

     ...
     ...

}

O problema dessa solução, na minha opinião, é conceitual: no meu domínio de negócio, meu Cliente (por exemplo) possui uma imagem que representa sua foto, e não um array de bytes.

Alguém tem uma solução mais elegante para esse problema?

9 Respostas

Guilherme_Gomes

Uma imagem é um array de bytes… Um arquivo no computador é armazenado em bytes… Essa a razão de você achar o pessoal usando byte[].

Mero_Aprendiz

Olá.
Porque você não cria dentro do seu Cliente mesmo métodos para transformar esse bytes[] em uma Image?

public class Cliente {

     private Image foto;

     public Image getFoto() {
          return foto;
     }

     public void setFoto(Image foto) {
          this.foto = foto;
     }

    @Transient 
    public Image getImagem(){
          /**
          * Aqui você transforma o bytes[] em Image
          **/
    }

    public Image setImagem(Image image){
          /**
          * Aqui você transforma o Image em byte[]
          **/
    }
}

P.S.: Nunca tentei persistir uma imagem sem ser de byte[]. O Hibernate não persiste um image?

[]'s
JL

alanbrasil1984

vou postar um método que tenho que ao colocar ele como href de uma imagem ele busca a imagem no banco e coloca na pag…

public ActionForward mostraFotoProfissional(ActionMapping mapping, ActionForm form,
			HttpServletRequest request, HttpServletResponse response) {
		
		Profissional profissional = null;
		
		
		Long a = Validacoes.validaNumero(request.getParameter("idProfissional"));

		profissional = profissionalFacade.getProfissionalById(a);
		
		try {
			
			byte[] photo = null;
					
			photo = profissional.getPessoaFisica().getFotografia();
		
			if(photo != null){
				response.setContentType("image/jpg");
				OutputStream os = response.getOutputStream();
				BufferedOutputStream bos = new BufferedOutputStream(os);
				bos.write(photo, 0, photo.length);
				bos.close();
			}
		} catch (IOException e) {
			e.printStackTrace();
		}
		
		return null;
	}

isso ai é um exemplo pratico…

espero ter ajudado

Lavieri
public class Cliente {  
     ...  
     @Transient private Image fotoImg; //ou seja isso aqui não é persistido
     private byte[] foto;  
  
     public Image getFoto() {
          return fotoImg;  
     }  
  
     public void setFoto(Image foto) {  
          this.foto = ((DataBufferByte)((BufferedImage)foto).getRaster().getDataBuffer()).getData();
          this.fotoImg = foto;
     }

     public void setFoto(byte[] foto) {  
          setFoto(Toolkit.getDefaultToolkit().createImage(foto));
     }

     @PostLoad //apos carregar do banco de dados, seta o campo fotoImg
     public void criaImg() {
          fotoImg = Toolkit.getDefaultToolkit().createImage(foto);
     }
}
P

Pessoal,

Obrigado pelas sugestões. Parece que vou realmente ter que “sujar” minhas classes de negócio com detalhes de implementação. Bom, fazer o quê, né?

Vou experimentar as sugestões e depois digo qual eu adotei. A princípio, a sugestão do Lavieri pareceu ser a mais simples. Muito obrigado a todos!

Lavieri

se vc quiser, pode criar uma Classe do tipo

@Embeddable

nessa classe vc pode imbutir os dados.... do byte e liberar a imagem.... abstraindo mais para seu bean...

@Embeddable
public class ImgByte {
   @Column(name="foto") //supondo que o nome do campo para image é foto
   private byte[] data;
   @Transient private Image image = null;
   
   public ImgByte() {}

   public ImgByte(byte[] data) {
      setImage(data);
   }

   public ImgByte(Image image) {
      setImage(image);
   }
   
   public void setImage(Image image) {
      this.data = (image == null) ? null : ((DataBufferByte)((BufferedImage)image).getRaster().getDataBuffer()).getData();
      this.image = image;
   }

   public void setImage(byte[] data) {
      this.data = data;
      this.image = (data == null) ? null : Toolkit.getDefaultToolkit().createImage(data);
   }

   public byte[] getData() {
      return data;
   }

   public Image getImage() {
      if (image == null && data != null)
          this.image = Toolkit.getDefaultToolkit().createImage(data);
      return image;
   }
}

ai la na sua classe... vc usa assim

public class Cliente {    
     ...    
     @Embedded
     private ImgByte foto;
    
     public Image getFoto() {  
          return (foto == null) ? null : foto.getImage();    
     }    
    
     public void setFoto(Image foto) {    
          this.foto = new ImgByte(foto); 
     }
     public void setFoto(byte[] data) {
          this.foto = new ImgByte(data);
     }
     public void setFoto(ImgByte imgByte) {
          this.foto = imgByte;
     }
     ...
}

agora na sua classe Cliente, fica tudo bem mais abstraido

alanbrasil1984

mais cuidado com os null pointer para fazer oque ele ta sugerindo vc tem que ter certeza que virá imagem.

Lavieri

agora não precisa mais ter certeza… todos os nulls ali usando Embeddable e Embedded já estão previstos… eu editei o post ^^

robertoJames

Bom dia pessoal,

estou com o mesmo problema do amigo acima só que um pouco diferente:

eu tenho um selectItem e quero que apareça a imagem ao lado de acordo com o selectItem escolhido:

<f:view>  
  
        <a4j:form id="form_ajax">  
          
        <h:panelGroup id="painel_img_pai" >  
           
         <h:selectOneMenu value="#{mediaBean.municipio.codigo}" id="codOrgao" >     
                        <f:selectItems value="#{mediaBean.listaDeMunicipios}" />    
                        <a4j:support  reRender="painel_orgao_externo" event="onchange"     
                action="#{mediaBean.mudarUrl}"/>   
                    </h:selectOneMenu>     
          
        <h:panelGroup id="painel_orgao_externo"   rendered="true">  
          
        <a4j:outputPanel>  
        <a4j:mediaOutput   element="img"   
            mimeType="image/jpeg"  
                    createContent="#{mediaBean.paint}"  
value="#{mediaBean.mediaData.caminhoImagem}"  
                    cacheable="false" session="false" style="width: 105px; height: 120px;"/>   
      
          
        </a4j:outputPanel>  
        </h:panelGroup>  
          
    </h:panelGroup>
public class MediaData implements Serializable{  
  
    private static final long serialVersionUID = 1L;  
    Integer Width=110;  
    Integer Height=50;  
    Color Background=new Color(0,0,0);  
    Color DrawColor=new Color(255,255,255);  
    private String caminhoImagem;  
    private String imagem = "";  
      
    //File teste = new File("c:\\img\\cachorro.jpg");  
      
      
      
      
      
    public byte[] getData() throws FileNotFoundException {  
            String imagem = this.getCaminhoImagem();  
            byte[] buffer = null;  
              
            if(imagem != null){  
              
            try {  
                  
                InputStream is = new FileInputStream(imagem);  
                buffer = new byte[is.available()];  
                is.read(buffer);  
                is.close();  
            } catch (IOException ex) {  
                ex.printStackTrace();  
            }  
            }  
            return buffer;  
              
    }

vocês saberiam me ajudar ?

Criado 7 de abril de 2009
Ultima resposta 29 de set. de 2010
Respostas 9
Participantes 6