Hi everyone,
I'm working on a web service that retrieves a blob from an Oracle DB and returns it to the client. Based on what I've read online, it seems that the best way to do this is to convert the blob to a byte array and return the byte array to the client.
Here is my class that was generated by Hibernate, and I added two methods to this class (toByteArray() and toByteArrayImpl())...
Code:
package ca.mcgill.muhc.oword;
// Generated 13-Jan-2011 11:22:02 AM by Hibernate Tools 3.3.0.GA
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.math.BigDecimal;
import java.sql.Blob;
import java.sql.SQLException;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;
/**
* OwordTemplates generated by hbm2java
*/
@Entity
@Table(name = "OWORD_TEMPLATES")
public class OwordTemplates implements java.io.Serializable {
private BigDecimal docId;
private String docType;
private String docName;
private Blob document;
public OwordTemplates() {
}
public OwordTemplates(BigDecimal docId, Blob document) {
this.docId = docId;
this.document = document;
}
public OwordTemplates(BigDecimal docId, String docType, String docName,
Blob document) {
this.docId = docId;
this.docType = docType;
this.docName = docName;
this.document = document;
}
@Id
@Column(name = "DOC_ID", unique = true, nullable = false, precision = 38, scale = 0)
public BigDecimal getDocId() {
return this.docId;
}
public void setDocId(BigDecimal docId) {
this.docId = docId;
}
@Column(name = "DOC_TYPE", length = 200)
public String getDocType() {
return this.docType;
}
public void setDocType(String docType) {
this.docType = docType;
}
@Column(name = "DOC_NAME")
public String getDocName() {
return this.docName;
}
public void setDocName(String docName) {
this.docName = docName;
}
@Column(name = "DOCUMENT", nullable = false)
public Blob getDocument() {
return this.document;
}
public void setDocument(Blob document) {
this.document = document;
}
public byte[] toByteArray(Blob fromBlob) {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
try
{
return toByteArrayImpl(fromBlob, baos);
} catch (SQLException e) {
throw new RuntimeException(e);
} catch (IOException e) {
throw new RuntimeException(e);
} finally {
if (baos != null) {
try {
baos.close();
} catch (IOException ex) {}
}
}
}
private byte[] toByteArrayImpl(Blob fromBlob, ByteArrayOutputStream baos) throws SQLException, IOException {
byte[] buf = new byte[4000];
InputStream is = fromBlob.getBinaryStream();
try {
for (;;) {
int dataSize = is.read(buf);
if (dataSize == -1)
break;
baos.write(buf, 0, dataSize);
}
} finally {
if (is != null) {
try {
is.close();
} catch (IOException ex) {}
}
}
return baos.toByteArray();
}
}
Here is the class with my query...
Code:
package ca.mcgill.muhc.oword;
import java.util.List;
import javax.ejb.Stateless;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;
import org.apache.log4j.Logger;
@Stateless
public class OwordTemplatesQueryBean implements OwordTemplatesQuery {
@PersistenceContext( unitName = "oword" )
EntityManager oword;
private static Logger log = Logger.getLogger( OwordTemplatesQueryBean.class );
private static final String GET_ALL_TEMPLATES = "select docId, docType, docName from OwordTemplates";
@SuppressWarnings( "unchecked" )
public List<OwordTemplates> getAllTemplates() {
log.info("Start of OwordTemplatesQueryBean.getAllTemplates method");
Query qry = oword.createQuery(GET_ALL_TEMPLATES);
return qry.getResultList();
}
}
Here is the method that the client application calls to get the blob (along with some other fields) and then converts the blob to byte[]...
This method is not fully complete.
Code:
public List<OwordTemplates> getRealTemplates() {
List<OwordTemplates> templates = owordTemplatesQuery.getAllTemplates();
log.info("Point 2");
for(int i=0; i < templates.size(); i++) {
OwordTemplates oTemplates = templates.get(i);
byte[] bretrived = oTemplates.toByteArray(oTemplates.getDocument());
ByteArrayInputStream bais = new ByteArrayInputStream(bretrived);
try {
ObjectInputStream obj = new ObjectInputStream(bais);
} catch (IOException e) {
e.printStackTrace();
}
}
return templates;
}
I get the following error on the first statement in the getRealTemplates() method...
Code:
10:02:59,703 ERROR [SOAPFaultHelperJAXWS] SOAP request exception
javax.ejb.EJBException: java.lang.NullPointerException
at org.jboss.ejb3.tx.Ejb3TxPolicy.handleExceptionInOurTx(Ejb3TxPolicy.java:63)
at org.jboss.aspects.tx.TxPolicy.invokeInOurTx(TxPolicy.java:83)
at org.jboss.aspects.tx.TxInterceptor$Required.invoke(TxInterceptor.java:191)
at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101)
at org.jboss.aspects.tx.TxPropagationInterceptor.invoke(TxPropagationInterceptor.java:94)
at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101)
at org.jboss.ejb3.stateless.StatelessInstanceInterceptor.invoke(StatelessInstanceInterceptor.java:70)
at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101)
at org.jboss.aspects.security.AuthenticationInterceptor.invoke(AuthenticationInterceptor.java:77)
at org.jboss.ejb3.security.Ejb3AuthenticationInterceptor.invoke(Ejb3AuthenticationInterceptor.java:139)
at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101)
at org.jboss.ejb3.ENCPropagationInterceptor.invoke(ENCPropagationInterceptor.java:46)
at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101)
at org.jboss.ejb3.asynchronous.AsynchronousInterceptor.invoke(AsynchronousInterceptor.java:106)
at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101)
at org.jboss.wsf.container.jboss42.InvocationHandlerEJB3.invoke(InvocationHandlerEJB3.java:103)
at org.jboss.ws.core.server.ServiceEndpointInvoker.invoke(ServiceEndpointInvoker.java:223)
at org.jboss.wsf.stack.jbws.RequestHandlerImpl.processRequest(RequestHandlerImpl.java:421)
at org.jboss.wsf.stack.jbws.RequestHandlerImpl.handleRequest(RequestHandlerImpl.java:286)
at org.jboss.wsf.stack.jbws.RequestHandlerImpl.doPost(RequestHandlerImpl.java:196)
at org.jboss.wsf.stack.jbws.RequestHandlerImpl.handleHttpRequest(RequestHandlerImpl.java:122)
at org.jboss.wsf.stack.jbws.EndpointServlet.service(EndpointServlet.java:84)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.jboss.web.tomcat.filters.ReplyHeaderFilter.doFilter(ReplyHeaderFilter.java:96)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:230)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:173)
at org.jboss.web.tomcat.security.SecurityAssociationValve.invoke(SecurityAssociationValve.java:182)
at org.jboss.web.tomcat.security.JaccContextValve.invoke(JaccContextValve.java:84)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:128)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:104)
at org.jboss.web.tomcat.service.jca.CachedConnectionValve.invoke(CachedConnectionValve.java:157)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:241)
at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:844)
at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:583)
at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:447)
at java.lang.Thread.run(Thread.java:619)
Caused by: java.lang.NullPointerException
at ca.mcgill.muhc.oword.TestOWordWSBean.getRealTemplates(TestOWordWSBean.java:99)
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:597)
at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:112)
at org.jboss.ejb3.interceptor.InvocationContextImpl.proceed(InvocationContextImpl.java:166)
at org.jboss.ejb3.interceptor.EJB3InterceptorsInterceptor.invoke(EJB3InterceptorsInterceptor.java:63)
at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101)
at org.jboss.ejb3.connectionmanager.CachedConnectionInterceptor.invoke(CachedConnectionInterceptor.java:57)
at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101)
at org.jboss.ejb3.entity.TransactionScopedEntityManagerInterceptor.invoke(TransactionScopedEntityManagerInterceptor.java:54)
at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101)
at org.jboss.ejb3.AllowedOperationsInterceptor.invoke(AllowedOperationsInterceptor.java:47)
at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101)
at org.jboss.aspects.tx.TxPolicy.invokeInOurTx(TxPolicy.java:79)
... 39 more
Any ideas why I'm getting this error?
Thanks!