在Hibernate / JSF应用程序中从MySQL数据库中检索Blob

时间:2010-10-25 10:43:53

标签: java hibernate jsf jsf-2

我在使用JSF 2.0应用程序中的java从数据库中正确检索blob数据时遇到了一些问题。我遇到的第一个问题是我的getb方法为Blob命名为“file”我得到一个错误,说“基本属性只能是以下类型......”基本上说我不能返回一个Blob对象。我的代码看起来像下面的内容。即使我的代码编译错误。我已经创建了一个测试方法(下面的代码的最后一部分)并尝试测试,但它给了我运行时错误。

控制器Bean

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获取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");
    }
}

我不确定我是否正确行事。任何帮助都会很棒。感谢。

2 个答案:

答案 0 :(得分:1)

  

在我的getb方法中,Blob名为“file”我得到一个错误,说“基本属性只能是以下类型......”基本上说我不能返回Blob对象。

实际上,java.sql.Blob不是Hibernate / JPA可以映射的持久字段或属性。 JPA规范如下:

  

2.1.1持久字段和属性

     

...

     

的持久字段或属性   实体可能具有以下内容   类型:Java原始类型;   java.lang.String;其他Java   可序列化的类型(包括包装器   原始类型,   java.math.BigInteger,   java.math.BigDecimaljava.util.Date,   java.util.Calendarjava.sql.Date,   java.sql.Timejava.sql.Timestamp,   用户定义的可序列化类型,   byte[]Byte[]char[]和   Character[]);枚举;实体类型   和/或实体类型的集合;   和可嵌入的类(参见章节   2.1.5)。

您应该使用Lob注释并更改属性类型。从规范:

  

9.1.19 Lob Annotation

     

Lob注释指定a   持久性属性或字段应该是   坚持作为一个大对象   数据库支持的大对象类型。   便携式应用程序应该使用   映射到a时的Lob注释   数据库Lob类型。 Lob   注释可以结合使用   使用Basic注释。一个Lob   可以是二元或字符   类型。 Lob类型是从中推断出来的   持久字段的类型或   属性,除了字符串和   基于字符的类型默认为   斑点。

     

...

     

示例1:

@Lob @Basic(fetch=EAGER)
@Column(name="REPORT")
protected String report;
     

示例2:

@Lob @Basic(fetch=LAZY)
@Column(name="EMP_PIC", columnDefinition="BLOB NOT NULL")
protected byte[] pic;

参考

  • JPA 1.0规范
    • 第2.1.1节“持久字段和属性”
    • 第9.1.19节“Lob注释”

  

我的确切要求是从数据库中检索Blob,无论是Blob还是byte [],无论什么工作,然后以某种方式将其转换为有效的InputStream对象。

ByteArrayInputStream(byte[])怎么样?

答案 1 :(得分:0)

我猜测Blob对象就是你的实体。 如果你打印它也可能会有所帮助。

确保Blob返回byte[]

@Basic(fetch = FetchType.LAZY)
@Lob             
@Column(length = 104857600, nullable = false)
private byte[] data;