@Lob e EJB

Bom dia.

Estamos desenvolvendo um projeto usando Swing na camada de apresentação e EJBs no back-end, e surgiu uma necessidade de gravar um arquivo no banco. Estamos mapeando o atributo na entidade da seguinte forma:

@Lob @Basic(fecthType=FetchType.EAGER) private byte[] arquivo;
Há um método no EJB que recupera as entidades correspondentes, porém sua execução lança um StreamCorruptedException (mensagem: “invalid type code: D0”). Não sabemos o porquê.

Alguém já conseguiu persistir/recuperar um campo @Lob usando EJB? O que estamos fazendo de errado?

Grato.

Eu faço isso, e sem problemas. Aliás faço da mesma forma que você.

Como está a coluna no banco de dados? Qual o banco e driver? Lembre-se que no Oracle o driver thin não suporta arquivos muito grandes, então você precisa usar o oci.

E como está a configuração do hibernate? Você está usando a propriedade para usar streams para campos blob?

Olá garcia-jj, muito obrigado pela atenção.

A coluna do banco de dados está como BLOB, e realmente estamos usando o driver thin. Não conhecíamos essa limitação do driver.

E essa propriedade para usar streams nos campos blob… Realmente não configuramos, vamos pesquisar e postar o resultado aqui.

eu uso da seguinte forma, não ha necessidade do EAGER.

@Column(name="IMAGEM")
@Lob
private byte[] imagem;

espero ter ajudado.

alanbrasil1984, nós precisamos configurar o fetch type como eager. De qualquer maneira, o erro continua aparecendo se o retirarmos.

tnaires, perguntei na verdade como está definida essa coluna no banco.

Sobre LAZY X EAGER, a spec não é clara sobre isso para Lobs, então por convenção as implementações são EAGER mesmo que você especifique lazy. Eu havia já escrito isso por aqui, mas perdi o tópico.

Sobre o stream, dê uma olhada aqui: http://docs.jboss.org/hibernate/stable/core/reference/en/html/session-configuration.html#configuration-optional-binarystreams

[edit]

Aqui achei meu post:

[quote]Embora haja o atributo fetch na anotação @Basic do JPA, lazy-load só é implementado para associações, e não para propriedades. As implementações JPA mais usadas que são Hibernate e Toplink/Eclipselink não implementam tal funcionalidade. Ou seja, não é exclusivo de lazy de blobs, mas lazy de qualquer propriedade.

Ou seja, você nunca vai conseguir fazer lazy-load de propriedades, mesmo que a spec diga que você pode. Não sei o real motivo de não ser implementado isso.

Uma sugestão: em um projeto meu possui uma classe chamada BinaryFile. Essa classe possui id, nome do arquivo, hash md5. O conteúdo do arquivo, no caso a propriedade que é lazy fica em outra classe associada via embeded. Ou seja, esse campo fica na mesma tabela, porém nas classes Java não.[/quote]

E do pessoal do Hibernate:

Obrigado pelas respostas. Realizamos as modificações sugeridas, mas continuou dando problema.
Conforme sugerido pelo pessoal do Hibernate, estamos quase decidindo por usar JDBC diretamente pra persistir e obter esse campo.

tnaires, estou achando que há algum erro na tabela e não no hibernate. Trabalhar com blobs é bem transparente.

Você pode nos mandar a definição da coluna no banco de dados?

Olá garcia-jj, o DML da coluna está da seguinte forma:

CREATE TABLE ... (...) arquivo BLOB, (...)
O schema não foi gerado pelo Hibernate. Quando criamos a coluna, simplesmente associamos o tipo BLOB a ela e não fizemos mais nenhuma configuração.

Obteve resultado usando OCI? Testou configurar o H3 para usar streams?

Uma sugestão que te dou é fazer teste com outro banco e até mesmo deixar ele criar a tabela e ver se funciona. Esse erro dá em qual momento? Quando você busca os dados ou quando você insere?

Olá garcia-jj, desculpe a demora na resposta.

Nós conseguimos gravar os dados corretamente. Já testamos os dados gravados e o arquivo está íntegro no banco. O problema ocorre ao tentarmos recuperá-los. Dentro do session bean o arquivo é lido corretamente, a exceção ocorre no momento de transferir a entidade correspondente para o cliente.

Configuramos o Hibernate pra usar streams e não deu certo. Quanto ao driver OCI, estamos lutando contra o Weblogic 10.3 pra utilizá-lo.

tnaires, acho que dá para fazer um teste nisso. Se no EJB tudo está certo, porém na hora de enviar para a tela está dando esse erro, então não parece ser erro do hibernate nem mesmo do driver jdbc.

Como você está passando o objeto? Há uma coisa que em aplicações distribuídas há (no seu caso swing está em uma jvm separada do módulo EJB) acho que você precisa de um DTO. Um teste que dá para fazer é criar um outro array de bytes e copiar os dados. A performance pode não ser boa, mas dá para testar.

Como está seu código do método que faz o get no arquivo?