@Lob e EJB  XML
Índice dos Fóruns » Persistência: Hibernate, JPA, JDBC e outros
Autor Mensagem
tnaires
GUJ Master
[Avatar]

Membro desde: 22/12/2003 08:05:58
Mensagens: 1678
Localização: Porto Alegre/RS - Natal/RN
Offline

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:

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.

Tarso Nunes Aires

Blog - http://cabritin.wordpress.com/
Delicious - http://delicious.com/tnaires
Twitter - @tnaires

garcia-jj
JWizard

Membro desde: 13/04/2009 22:11:50
Mensagens: 2715
Localização: Porto Alegre
Offline

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?
tnaires
GUJ Master
[Avatar]

Membro desde: 22/12/2003 08:05:58
Mensagens: 1678
Localização: Porto Alegre/RS - Natal/RN
Offline

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.

Tarso Nunes Aires

Blog - http://cabritin.wordpress.com/
Delicious - http://delicious.com/tnaires
Twitter - @tnaires

alanbrasil1984
JavaEvangelist
[Avatar]

Membro desde: 23/07/2006 00:27:57
Mensagens: 359
Localização: Rio de janeiro
Offline

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



espero ter ajudado.



Alan Rodrigo de Oliveira Souza
Fattoria Web
Em busca da SCJP.

[WWW] [MSN] [ICQ]
tnaires
GUJ Master
[Avatar]

Membro desde: 22/12/2003 08:05:58
Mensagens: 1678
Localização: Porto Alegre/RS - Natal/RN
Offline

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

Tarso Nunes Aires

Blog - http://cabritin.wordpress.com/
Delicious - http://delicious.com/tnaires
Twitter - @tnaires

garcia-jj
JWizard

Membro desde: 13/04/2009 22:11:50
Mensagens: 2715
Localização: Porto Alegre
Offline

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

Oracle limits the size of byte arrays that can be passed to and/or from its JDBC driver. If you wish to use large instances of binary or serializable type, you should enable hibernate.jdbc.use_streams_for_binary. This is a system-level setting only.


[edit]

Aqui achei meu post:

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.


E do pessoal do Hibernate:

Typically the entire LOB will be read and written for the attribute. For very large LOBs reading the value always, or reading the entire value may not be desired. The fetch type of the Basic could be set to LAZY to avoid reading a LOB unless accessed. Support for LAZY fetching on Basic is optional in JPA, so some JPA providers may not support it. A workaround, which is often a good idea in general given the large performance cost of LOBs, is to store the LOB in a separate table and class and define a OneToOne to the LOB object instead of a Basic. If the entire LOB is never desired to be read, then it should not be mapped. It is best to use direct JDBC to access and stream the LOB in this case. In may be possible to map the LOB to a java.sql.Blob/java.sql.Clob in your object to avoid reading the entire LOB, but these require a live connection, so may have issues with detached objects.

This message was edited 2 times. Last update was at 02/12/2009 13:37:06

tnaires
GUJ Master
[Avatar]

Membro desde: 22/12/2003 08:05:58
Mensagens: 1678
Localização: Porto Alegre/RS - Natal/RN
Offline

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.

Tarso Nunes Aires

Blog - http://cabritin.wordpress.com/
Delicious - http://delicious.com/tnaires
Twitter - @tnaires

garcia-jj
JWizard

Membro desde: 13/04/2009 22:11:50
Mensagens: 2715
Localização: Porto Alegre
Offline

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?
tnaires
GUJ Master
[Avatar]

Membro desde: 22/12/2003 08:05:58
Mensagens: 1678
Localização: Porto Alegre/RS - Natal/RN
Offline

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

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.

Tarso Nunes Aires

Blog - http://cabritin.wordpress.com/
Delicious - http://delicious.com/tnaires
Twitter - @tnaires

garcia-jj
JWizard

Membro desde: 13/04/2009 22:11:50
Mensagens: 2715
Localização: Porto Alegre
Offline

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?
tnaires
GUJ Master
[Avatar]

Membro desde: 22/12/2003 08:05:58
Mensagens: 1678
Localização: Porto Alegre/RS - Natal/RN
Offline

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.

Tarso Nunes Aires

Blog - http://cabritin.wordpress.com/
Delicious - http://delicious.com/tnaires
Twitter - @tnaires

garcia-jj
JWizard

Membro desde: 13/04/2009 22:11:50
Mensagens: 2715
Localização: Porto Alegre
Offline

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?
 
Índice dos Fóruns » Persistência: Hibernate, JPA, JDBC e outros
Ir para:   
Powered by JForum 2.1.8 © JForum Team