3

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 out 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.

1
  • Unrelated to the actual problem: catch(HibernateException e) { throw new HibernateException(e); } that part is entirely superfluous. Remove it :) Commented Oct 25, 2010 at 17:39

2 Answers 2

1

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[], and Character[]); 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 the Basic annotation. A Lob may be either a binary or character type. The Lob 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[])?

Sign up to request clarification or add additional context in comments.

5 Comments

So if I did this how would I retrieve the data? I need to get the data as a Blob object so I can call the getInputStream method on it. if I change it to a byte[] I can not call this method anymore.
@NewTOJSF So if I did this how would I retrieve the data? By using the getter? I need to get the data as a Blob object so I can call the getInputStream method on it. And why do you need this? Where did you mention that in your question? What are your exact requirements?
Well my exact requiredments 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. I am using primefaces so I am trying to use their Dyna Image feature which will serve the images for me. In order to get the InputStream object I am under the assumption I need to call the getBinaryStream() method on the blob object. I have searched how to convert a byte[] array to an InputStream but I have not found anything that looks promising. Again I am very new to this so I am sorry for any confusion.
@NewTOJSF: No problem, it's just that readers can't guess what you're trying to achieve if you don't tell them :) I'll update my answer.
Thank you, sorry for the confusion.
0

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;

1 Comment

I don't understand when you say make sure your Blob returns byte[]. Can you possibly elaborate on that? Thanks.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.