Recuperação de Blob do banco de dados MySQL no Hibernate / JSF aplicação
Pergunta
Estou tendo alguns problemas corretamente recuperar dados blob do meu banco de dados usando o java no meu JSF 2.0 do aplicativo.O primeiro problema que eu estou tendo é no meu método getter para o Blob denominado "arquivo", recebo um erro dizendo que "atributos Básicos só podem ser dos seguintes tipos de..." basicamente dizendo que eu não posso retornar um objeto Blob.Meu código é como o que está abaixo.Mesmo com o erro meu código é compilado.Eu ter criado um método de teste (o último bit de código abaixo) e tentei testar, mas ele me dá erros de tempo de execução.
Controlador De Feijão
import java.sql.Blob;
@Entity
@Table(named = "files")
@NamedQueries( {
@NamedQuery(name = "MyBlob.getBlob",
query = from MyBlob WHERE fileId =: fileId")
})
public class MyBlob implements Serializable {
private Integer fileId;
private Blob file;
...
public Integer getFileId() {
return fileId;
}
public void setFileId() {
this.fileId = fileId;
}
public Blob getFile() {
return file;
}
public void setFile(Blob file) {
this.file = file;
}
....
}
BlobDao.java método de Arquivo para obter blob
public MyBlob getBlob(Integer fileId) throws HibernateException {
Session session = getSessionFactory().openSession();
try {
MyBlob blob = (MyBlob)session.getNamedQuery("MyBlob.getBlob").setInteger("fileId", fileId).uniqueResult();
return blob;
} catch(HibernateException e) {
throw new HibernateException(e);
} finally {
session.close();
}
}
TestDao.java
@Test
public void testBlob() {
MyBlob test = blobdao.getBlob(1); // 1 is a fileId that exists in the DB with a blob image file.
Blob blob = test.getFile();
try {
System.out.println(blob.length)); //this prints a number but I dont think the right one.
if(blob.length > 0 ) {
System.out.println(blob.toString() ); //errors out here
}
} catch(SQLException e) {
return System.out.println("Failed");
}
}
Não tenho certeza de que estou fazendo isso direito.Qualquer ajuda seria ótimo.Obrigado.
Solução
no meu método getter para o Blob denominado "arquivo", recebo um erro dizendo que "atributos Básicos só podem ser dos seguintes tipos de..." basicamente dizendo que eu não posso retornar um objeto Blob.
De fato, um java.sql.Blob
não é um campo persistente ou propriedade que pode ser mapeado pelo Hibernate/JPA.A especificação JPA coloca é como este:
2.1.1 Campos Persistentes e Propriedades
...
Os campos persistentes ou propriedades de uma entidade pode ser um dos seguintes tipos:Tipos primitivos de Java;
java.lang.String
;outra Java serializable tipos (incluindo wrappers dos tipos primitivos,java.math.BigInteger
,java.math.BigDecimal
,java.util.Date
,java.util.Calendar
,java.sql.Date
,java.sql.Time
,java.sql.Timestamp
, definido pelo usuário tipos serializáveis,byte[]
,Byte[]
,char[]
, eCharacter[]
);as enumerações;tipos de entidade e/ou coleções de tipos de entidade;e incorporável classes (ver secção 2.1.5).
Você provavelmente deve usar o Lob
anotação e alterar o seu tipo de atributo.A partir da especificação:
9.1.19 Lob Anotação
Um Lob anotação especifica que um persistente propriedade ou campo deve ser persistente como um objeto grande para um base de dados-suporte grande tipo de objeto.Aplicações portáteis deve usar o Lob anotação quando o mapeamento para um banco de dados do tipo Lob.O
Lob
anotação podem ser utilizados em conjunto com oBasic
anotação.UmLob
pode ser um binário ou de caráter escreva.OLob
tipo é inferido a partir de o tipo de campo persistente ou propriedade, e, exceto para a cadeia e personagem baseado em tipos padrão para Blob....
Exemplo 1:
@Lob @Basic(fetch=EAGER) @Column(name="REPORT") protected String report;
Exemplo 2:
@Lob @Basic(fetch=LAZY) @Column(name="EMP_PIC", columnDefinition="BLOB NOT NULL") protected byte[] pic;
Referências
- JPA 1.0 especificação
- Seção 2.1.1 "Campos Persistentes e Propriedades"
- Seção 9.1.19 "Lob Anotação"
Bem, a minha exata requisitos para obter o Blob do banco de dados como um Blob ou um byte[], o que funciona e, em seguida, de alguma forma, converter isso em um válido InputStream objeto.
O que sobre ByteArrayInputStream(byte[])
?
Outras dicas
Estou supondo o Blob
Objeto é sua entidade. Pode ajudar se você imprimir isso também.
Certifique -se de que você Blob
retorna byte[]
@Basic(fetch = FetchType.LAZY)
@Lob
@Column(length = 104857600, nullable = false)
private byte[] data;