在 Hibernate/JSF 应用程序中从 MySQL 数据库检索 Blob
题
我在 JSF 2.0 应用程序中使用 java 从数据库中正确检索 blob 数据时遇到一些问题。我遇到的第一个问题是在名为“file”的 Blob 的 getter 方法上,我收到一条错误消息,指出“基本属性只能是以下类型...”,基本上是说我无法返回 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");
}
}
我不确定我这样做是否正确。任何帮助都会很棒。谢谢。
解决方案
在名为“file”的 Blob 的 getter 方法中,我收到一条错误消息,指出“基本属性只能是以下类型...”,基本上是说我无法返回 Blob 对象。
确实,一个 java.sql.Blob
不是 Hibernate/JPA 可以映射的持久字段或属性。JPA规范是这样的:
2.1.1 持久化字段和属性
...
实体的持久字段或属性可能是以下类型:Java 原始类型;
java.lang.String
;其他Java序列化类型(包括原始类型的包装器,java.math.BigInteger
,java.math.BigDecimal
,java.util.Date
,java.util.Calendar
,java.sql.Date
,java.sql.Time
,java.sql.Timestamp
,用户定义的可序列化类型,byte[]
,Byte[]
,char[]
, , 和Character[]
);枚举;实体类型的实体类型和/或集合;和可嵌入的类(请参阅第2.1.5节)。
你可能应该使用 Lob
注释并更改您的属性类型。从规格来看:
9.1.19 吊球注释
LOB注释指定持久性属性或字段应将其作为数据库支持的大对象类型的大对象持续存在。映射到数据库LOB类型时,便携式应用程序应使用LOB注释。这
Lob
注释可以与Basic
注解。ALob
可以是二进制或字符类型。这Lob
类型是从持久性字段或属性的类型中推断出的,除了基于字符串和基于字符的类型默认为BLOB。...
示例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 或 byte[] 的形式检索 Blob,无论什么都有效,然后以某种方式将其转换为有效的 InputStream 对象。
其他提示
我猜Blob
对象是你的实体。
如果您打印以及它可能的帮助。
请确保您的Blob
回报byte[]
@Basic(fetch = FetchType.LAZY)
@Lob
@Column(length = 104857600, nullable = false)
private byte[] data;