Retrieving Blob from MySQL database in Hibernate / JSF application
I am having some trouble properly retrieving blob data from my database using java in my JSF 2.0 application. The first problem I am having is on my getter method for the Blob named "file" I get an error saying that "Basic attributes can only be of the following types..." basically saying that I can not return a Blob object. My code looks like what is below. Even with the error my code compiles. I have created a test method (the last bit of code below) and tried to test but it gives me runtime errors.
Controller 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 File method to get 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 o开发者_开发技巧ut here
}
} catch(SQLException e) {
return System.out.println("Failed");
}
}
I am not sure that I am doing this right at all. Any help would be great. Thanks.
on my getter method for the Blob named "file" I get an error saying that "Basic attributes can only be of the following types..." basically saying that I can not return a Blob object.
Indeed, a java.sql.Blob
is not a persistent field or property that can be mapped by Hibernate/JPA. The JPA specification puts is like this:
2.1.1 Persistent Fields and Properties
...
The persistent fields or properties of an entity may be of the following types: Java primitive types;
java.lang.String
; other Java serializable types (including wrappers of the primitive types,java.math.BigInteger
,java.math.BigDecimal
,java.util.Date
,java.util.Calendar
,java.sql.Date
,java.sql.Time
,java.sql.Timestamp
, user-defined serializable types,byte[]
,Byte[]
,char[]
, andCharacter[]
); enums; entity types and/or collections of entity types; and embeddable classes (see section 2.1.5).
You should probably use the Lob
annotation and change your attribute type. From the specification:
9.1.19 Lob Annotation
A Lob annotation specifies that a persistent property or field should be persisted as a large object to a database-supported large object type. Portable applications should use the Lob annotation when mapping to a database Lob type. The
Lob
annotation may be used in conjunction with theBasic
annotation. ALob
may be either a binary or character type. TheLob
type is inferred from the type of the persistent field or property, and except for string and character-based types defaults to Blob....
Example 1:
@Lob @Basic(fetch=EAGER) @Column(name="REPORT") protected String report;
Example 2:
@Lob @Basic(fetch=LAZY) @Column(name="EMP_PIC", columnDefinition="BLOB NOT NULL") protected byte[] pic;
References
- JPA 1.0 specification
- Section 2.1.1 "Persistent Fields and Properties"
- Section 9.1.19 "Lob Annotation"
Well my exact requirements are to retrieve the Blob from the database either as a Blob or a byte[], whatever works, and then somehow convert that into a valid InputStream object.
What about ByteArrayInputStream(byte[])
?
I am guessing the Blob
object is your Entity.
It might help if you print that as well.
Make sure your Blob
returns byte[]
@Basic(fetch = FetchType.LAZY)
@Lob
@Column(length = 104857600, nullable = false)
private byte[] data;
精彩评论