-->
These old forums are deprecated now and set to read-only. We are waiting for you on our new forums!
More modern, Discourse-based and with GitHub/Google/Twitter authentication built-in.

All times are UTC - 5 hours [ DST ]



Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 7 posts ] 
Author Message
 Post subject: Retrieving and displaying image
PostPosted: Tue May 09, 2006 6:28 pm 
Newbie

Joined: Fri Mar 24, 2006 1:28 pm
Posts: 6
Hello,


I'm trying to retrieve an image stored as a blob in the database and displaying it on the web browser using hibernate 3.0 and struts. I run into problems when I try and use either the getBytes() method or the getBinaryStream() methods on the blob data. Following is my code:

ShowImageAction using getBytes():

public class ShowImageAction {

static Logger logger = Logger.getLogger(ShowImageAction.class);

// --------------------------------------------------------- Instance Variables
HttpSession httpsession;
Images img;
Blob imgdata;
OutputStream out;
byte[] databuffer;
InputStream is;
int bytesread;

// --------------------------------------------------------- Methods


/**
* Method execute
* @param mapping
* @param form
* @param request
* @param response
* @return ActionForward
*/
public ActionForward execute(
ActionMapping mapping,
ActionForm form,
HttpServletRequest request,
HttpServletResponse response) {


ShowImageForm showImageForm = (ShowImageForm) form;

httpsession = request.getSession();


img = (Images)httpsession.getAttribute("image");

// retrieve the blob data for the image using the getter method
imgdata = img.getImagData();


try{
databuffer = imgdata.getBytes(1, (int)imgdata.length());
logger.info("databuffer:" + databuffer);
out = response.getOutputStream();
out.write(databuffer);
out.close();

}catch(Exception e){
e.printStackTrace();
}
return null;

}

}

My jsp file is as follows:

<table>
<tr>
<td align="center"> Page Title: <bean:write name="sbcover" property="sbTitle"/></td>
<td align="center"> Author: <bean:write name="sbcover" property="author"/></td>
<td align="center"> Date: <bean:write name="sbcover" property="date"/></td>
</tr> <br></br>
<tr align="center">
<td> <html:img page="/showImage.do" height="200" width="200" alt="image1" /> </td>
</tr>
<logic:present name="image">
<tr align="center">
<td><bean:write name="image" property="caption"/> </td>
</tr>
</logic:present>
<logic:present name="txtpanel">
<tr align="center">
<td><bean:write name="txtpanel" property="textData"/> </td>
</tr>
</logic:present>
<table>
</body>

When i execute this, I get the following error:

java.lang.UnsupportedOperationException: Blob may not be manipulated from creating session
at org.hibernate.lob.BlobImpl.excep(BlobImpl.java:104)
at org.hibernate.lob.BlobImpl.getBytes(BlobImpl.java:50)
at org.hibernate.lob.SerializableBlob.getBytes(SerializableBlob.java:35)
at com.osb.struts.action.ShowImageAction.execute(ShowImageAction.java:88)
at org.apache.struts.action.RequestProcessor.processActionPerform(RequestProcessor.java:419)
at org.apache.struts.action.RequestProcessor.process(RequestProcessor.java:224)
at org.apache.struts.action.ActionServlet.process(ActionServlet.java:1194)
at org.apache.struts.action.ActionServlet.doGet(ActionServlet.java:414)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:747)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:860)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:585)
at org.apache.catalina.security.SecurityUtil$1.run(SecurityUtil.java:249)
at java.security.AccessController.doPrivileged(Native Method)
at javax.security.auth.Subject.doAsPrivileged(Subject.java:517)
at org.apache.catalina.security.SecurityUtil.execute(SecurityUtil.java:282)
at org.apache.catalina.security.SecurityUtil.doAsPrivilege(SecurityUtil.java:165)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:257)
at org.apache.catalina.core.ApplicationFilterChain.access$000(ApplicationFilterChain.java:55)
at org.apache.catalina.core.ApplicationFilterChain$1.run(ApplicationFilterChain.java:161)
at java.security.AccessController.doPrivileged(Native Method)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:157)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:263)
at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:551)
at org.apache.catalina.core.StandardContextValve.invokeInternal(StandardContextValve.java:225)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:173)
at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:551)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:170)
at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:551)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:132)
at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:551)
at org.apache.catalina.core.ContainerBase.invoke(ContainerBase.java:933)
at org.apache.coyote.tomcat5.CoyoteAdapter.service(CoyoteAdapter.java:189)
at com.sun.enterprise.web.connector.grizzly.ProcessorTask.doProcess(ProcessorTask.java:604)
at com.sun.enterprise.web.connector.grizzly.ProcessorTask.process(ProcessorTask.java:475)
at com.sun.enterprise.web.connector.grizzly.ReadTask.executeProcessorTask(ReadTask.java:371)
at com.sun.enterprise.web.connector.grizzly.ReadTask.doTask(ReadTask.java:264)
at com.sun.enterprise.web.connector.grizzly.TaskBase.run(TaskBase.java:281)
at com.sun.enterprise.web.connector.grizzly.WorkerThread.run(WorkerThread.java:83)

I noticed that in the BlobImpl class, only getBinaryStream() and length() methods are implemented. I therefore changed my "ShowImageAction" class to use getBinaryStream instead:

public class ShowImageAction {

static Logger logger = Logger.getLogger(ShowImageAction.class);

// --------------------------------------------------------- Instance Variables
HttpSession httpsession;
Images img;
Blob imgdata;
OutputStream out;
byte[] databuffer;
InputStream is;
int bytesread;

// --------------------------------------------------------- Methods


/**
* Method execute
* @param mapping
* @param form
* @param request
* @param response
* @return ActionForward
*/
public ActionForward execute(
ActionMapping mapping,
ActionForm form,
HttpServletRequest request,
HttpServletResponse response) {

logger.info("into showImageAction");
ShowImageForm showImageForm = (ShowImageForm) form;

httpsession = request.getSession();


img = (Images)httpsession.getAttribute("image");
imgdata = img.getImagData();
logger.info("imgdata:" + imgdata);

databuffer = new byte[2048];

try{
is = imgdata.getBinaryStream();
out = response.getOutputStream();
while ((bytesread = is.read(databuffer)) != -1) {
out.write(databuffer, 0, bytesread);
}
out.close();

}catch(Exception e){
e.printStackTrace();
}
return null;

}

}

When I executed this, I got the following error:

java.sql.SQLException: could not reset reader
at org.hibernate.lob.BlobImpl.getBinaryStream(BlobImpl.java:83)
at org.hibernate.lob.SerializableBlob.getBinaryStream(SerializableBlob.java:39)
at com.osb.struts.action.ShowImageAction.execute(ShowImageAction.java:81)
at org.apache.struts.action.RequestProcessor.processActionPerform(RequestProcessor.java:419)
at org.apache.struts.action.RequestProcessor.process(RequestProcessor.java:224)
at org.apache.struts.action.ActionServlet.process(ActionServlet.java:1194)
at org.apache.struts.action.ActionServlet.doGet(ActionServlet.java:414)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:747)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:860)
at sun.reflect.GeneratedMethodAccessor107.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:585)
at org.apache.catalina.security.SecurityUtil$1.run(SecurityUtil.java:249)
at java.security.AccessController.doPrivileged(Native Method)
at javax.security.auth.Subject.doAsPrivileged(Subject.java:517)
at org.apache.catalina.security.SecurityUtil.execute(SecurityUtil.java:282)
at org.apache.catalina.security.SecurityUtil.doAsPrivilege(SecurityUtil.java:165)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:257)
at org.apache.catalina.core.ApplicationFilterChain.access$000(ApplicationFilterChain.java:55)
at org.apache.catalina.core.ApplicationFilterChain$1.run(ApplicationFilterChain.java:161)
at java.security.AccessController.doPrivileged(Native Method)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:157)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:263)
at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:551)
at org.apache.catalina.core.StandardContextValve.invokeInternal(StandardContextValve.java:225)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:173)
at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:551)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:170)
at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:551)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:132)
at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:551)
at org.apache.catalina.core.ContainerBase.invoke(ContainerBase.java:933)
at org.apache.coyote.tomcat5.CoyoteAdapter.service(CoyoteAdapter.java:189)
at com.sun.enterprise.web.connector.grizzly.ProcessorTask.doProcess(ProcessorTask.java:604)
at com.sun.enterprise.web.connector.grizzly.ProcessorTask.process(ProcessorTask.java:475)
at com.sun.enterprise.web.connector.grizzly.ReadTask.executeProcessorTask(ReadTask.java:371)
at com.sun.enterprise.web.connector.grizzly.ReadTask.doTask(ReadTask.java:264)
at com.sun.enterprise.web.connector.grizzly.TaskBase.run(TaskBase.java:281)
at com.sun.enterprise.web.connector.grizzly.WorkerThread.run(WorkerThread.java:83)

Any idea why I would get this error. I tried searching for a solution on the web and the hibernate forum and spent a lot of time and effort trying work arounds but haven't succeeded. I would greatly appreciate it if anyone who has some insight into this problem can help out. I can supply additional info if required. Thanks!


Top
 Profile  
 
 Post subject:
PostPosted: Tue May 09, 2006 7:21 pm 
Expert
Expert

Joined: Thu Dec 23, 2004 9:08 pm
Posts: 2008
Blobs are very database-specific, and you don't say what DBMS you're using, so this is only a guess. Most databases only support reading blobs from within the transaction that they're retrieved: this is because the thing that goes into the result set isn't the blob data, it's a reference to it. The reference needs to be looked up in order to get the data, and that only works inside the transaction. It's likely that you're trying to read the blob data outside of the transaction.

My solution to lobs has been to map all of a table's lobs to a separate java class, mapped to the "main" class for the table via a lazy one-to-one. Then I have two factory methods for reading rows from the main class: a default one (that just calls session.get()), and a get-with-lobs one that uses HQL's "join fetch" syntax to get the lob data with the main object. When that method is used, it guarantees that the lob data is fetched in the initial transaction, no matter what happens to the session afterwards.

_________________
Code tags are your friend. Know them and use them.


Top
 Profile  
 
 Post subject:
PostPosted: Thu May 11, 2006 4:50 pm 
Newbie

Joined: Fri Mar 24, 2006 1:28 pm
Posts: 6
Hi,

Thanks for your response. It turns out that if you use the getInputStream() method of the FormFile interface while creating a blob in hibernate, you can run into this problem when you later try and retrieve the blob from your session. Here's what I was trying to do:

I received an image from a user as a FormFile (say called "imgFile")

I then created a blob using the org.hibernate.Hibernate.createBlob() method by passing it the argument: imgFile.getInputStream()

I then inserted the blob into the database and also saved it my session using setAttribute()

I then tried retrieving the image from my session (not database) and tried to display it to the reader. This is when I got the errors.

I think the reason I was got the "cannot reset reader" error is because of the type of InputStream that FormFile generates. It probably does not support the reset() method and hence I got the error when I tried to use the getBinaryStream() method when trying to retrieve it.

I solved this by using the byte[] construtor for createBlob() instead of the InputStream. I read all the bytes into a buffer and passed it as the argument into the createBlob() method. This would ensure I'm not using an input stream that hibernate cannot interpret.

It works just fine now!


Top
 Profile  
 
 Post subject:
PostPosted: Wed Aug 16, 2006 4:19 am 
Newbie

Joined: Wed May 17, 2006 5:10 am
Posts: 14
hi arao06;
I've the same problem, would u mind sending me your code which solve the problem ?

thnx alot


Top
 Profile  
 
 Post subject:
PostPosted: Sun Jul 15, 2007 12:00 am 
Newbie

Joined: Sat Jul 14, 2007 11:41 pm
Posts: 1
Hello!

Im having exactly the same error.
Code:
java.lang.UnsupportedOperationException: Blob may not be manipulated from creating session


Im using MySQL 4.1, Java 1.4 and Tomcat 4.1.

Im not using Hibernate for anything else that converting from FormFile to Blob type, as its specified in this lines:

Code:

public synchronized boolean subirArchivo(String nombre, FormFile file, int sector) throws Exception {
        ConexionBD conn = new ConexionBD();
        try{
           /* The Hibernate class (in hibernate3.jar) converts to BLOB type the file that comes as FormFile */
           Blob fileBlob = Hibernate.createBlob(file.getInputStream());
           
            boolean r = GestorArchivo.getInstancia().registrarArchivo(conn, nombre, fileBlob, sector);
            return r;
        }catch (SQLException ex){
                             ...


As you can see, I use the getInputStream() as a parameter of the createBlob() method, but I also get the exception if the parameter is "file.getFileData()". This didnt resolve the problem.

The exception is ocurring when im trying to insert the Blob in the PreparedStatement:

Code:
public synchronized boolean registrarArchivo(ConexionBD conn, String nombre, Blob file, int sector) throws SQLException {
        String consulta = "INSERT INTO TArchivo VALUES (default, ?, ?, ?)";
       
        try{
           conn.setSQL(consulta);
            conn.setString(1, nombre);
            [b]conn.setBlob(2, file);[/b]
            conn.setInt(3, sector);
        }catch(Exception e){
           e.printStackTrace();
        }
...


That line in bold is where the app brakes down.

Please, if you could give some help I'll appreciate it a lot!


Top
 Profile  
 
 Post subject:
PostPosted: Sat Mar 29, 2008 11:29 am 
Newbie

Joined: Sat Mar 29, 2008 11:12 am
Posts: 6
Location: USA
Hi arao06,

Don't you mind to share with me a working solution for a subject being discussed here? I need an example of displaying images in JSP that I have currently stored in MySQL 5.0 database as BLOB objects. I'm using combination of Hibernate 3.2 and Struts 1.3 plus Tomcat 5.5.

Any help would be greatly appreciated.


Top
 Profile  
 
 Post subject: Re: Retrieving and displaying image
PostPosted: Thu Nov 17, 2011 2:55 am 
Newbie

Joined: Thu Nov 17, 2011 2:05 am
Posts: 3
I have a thick client application in which I want to save an image into DB. I am sending an the as a byte[]

byte[] array = ImageClass.getImageBytes(imagePath);

the byte[] is converted to a SerialBlob in setAttributes methode in POJO

my bean class

public class School {
private int schoolId;
private String schoolName;
private Blob logo;
private String schoolType;

public School(){
}

public Integer getSchoolId() {
return this.schoolId;
}

public void setSchoolId(Integer schoolId) {
this.schoolId = schoolId;
}

public String getSchoolName() {
return this.schoolName;
}

public void setSchoolName(String schoolName) {
this.schoolName = schoolName;
}

public Blob getLogo() {
return this.logo;
}

public void setLogo(Blob logo) {
this.logo = logo;
}


public String getSchoolType() {
return this.schoolType;
}

public void setschoolType(String schoolType) {
this.schoolType = schoolType;
}


public void setAttributes(HashMap dto){

schoolName = (String)dto.get(DTOFactory.School.SCHOOL_NAME);
schoolType = (String)dto.get(DTOFactory.School.TYPE);
logo = new SerialBlob((byte[])dto.get(DTOFactory.School.LOGO));

}

public HashMap getAttributes(){
HashMap dto = DTOFactory.getSchoolDTO();
dto.put(DTOFactory.School.SCHOOL_NAME, getSchoolName());
dto.put(DTOFactory.School.LOGO, getLogo());
dto.put(DTOFactory.School.TYPE, getSchoolType());

return dto;
}
}

And my mapping file

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class entity-name="school" name="erp.domain.School" table="efe_school">
<id column="SCHOOL_ID" name="schoolId" type="int">
<generator class="native"/>
</id>

<property name="schoolName">
<column name="SCHOOL_NAME"/>
</property>


<property name="logo" type="blob">
<column name="LOGO"/>
</property>

<property name="schoolType">
<column name="SCHOOL_TYPE"/>
</property>

</class>
</hibernate-mapping>


then its saved in my dao class

@Transactional(readOnly = false, propagation = Propagation.REQUIRES_NEW)
public void create(HashMap dto) {
School school = new School();
school.setAttributes(dto);
sessionFactory.getCurrentSession().save("school",school);
}



All these are working fine and the image is saved in DB

And retrives the data in Dao class like


public HashMap load() {
School school = (School)sessionFactory.getCurrentSession().createQuery("from edp.domain.School").uniqueResult();
return school.getAttributes();

}

the data is reached at the alient side and I trying to put the Image back in a JLabel

Blob image = ((Blob)response.get(LOGO));
byte[] array = ImageClass.getImageBytes(image);
ImageIcon imageIcon = new ImageIcon(array);
schoolImageLabel.setIcon(imageIcon);

ImageClass is used to retrievebytes from the blob,


ImageClass.getImageBytes() methode looks like

public static byte[] getImageBytes(Blob blob){
try {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
byte[] buf = new byte[1024];
InputStream in = ((Blob)blob).getBinaryStream();

int n = 0;
while ((n=in.read(buf))>=0)
{
baos.write(buf, 0, n);
}
in.close();
byte[] bytes = baos.toByteArray();
return bytes;
} catch(Exception e) {
System.err.println("blob to byte[] : " + e);
}
return null;
}


Here what i am getting is an exception :

"java.lang.IllegalStateException:Blogs may not be accessed after serialization"

My doubt is that is it not get serialized at the time of retrieval from DB.

also when I tried to convert to serialBlob at client side

SerialBlob image = ((SerialBlob)response.get(LOGO));
byte[] array = ImageClass.getImageBytes(image);
ImageIcon imageIcon = new ImageIcon(array);
schoolImageLabel.setIcon(imageIcon);

an exception got like : org.hibernate.lob.SerializableBlob cannot be converted to javax.sql.rowset.serial.SerialBlob


Please help I am stuck with this for a long time. Any help will be greatly appreciated. Thanks in advance


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 7 posts ] 

All times are UTC - 5 hours [ DST ]


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Search for:
© Copyright 2014, Red Hat Inc. All rights reserved. JBoss and Hibernate are registered trademarks and servicemarks of Red Hat, Inc.