Skip to Main Content

Java Development Tools

Announcement

For appeals, questions and feedback about Oracle Forums, please email oracle-forums-moderators_us@oracle.com. Technical questions should be asked in the appropriate category. Thank you!

Interested in getting your voice heard by members of the Developer Marketing team at Oracle? Check out this post for AppDev or this post for AI focus group information.

EJB with Rest service to return a blob

DLopezAug 11 2015 — edited Aug 14 2015

Hi,

I've been working with EJB and Rest Services and now I have this situation.

I'm trying to present an image saved on my DB as a blob, but when I test my service I get no results.

My entity as the following code for the blob, self generated

private byte[] thememo;

    public byte[] getThememo() {

        return thememo;

    }

    public void setThememo(byte[] thememo) {

        this.thememo = thememo;

    }

and this are the queries, both to return the same, that I've added

@NamedQuery(name = "Memos.findPhoto", query = "select o.thememo from Memos o where o.sourceid = :recid and o.memotyp = 101"),

@NamedQuery(name = "Memos.getPhoto", query = "select 'image/jpeg', o.thememo from Memos o where o.sourceid = :recid and o.memotyp = 101")

when looking for something that would explain me on how to accomplish what I want I found a link indicating to add this 'image/jpeg', before the column that as the blob

and when I add those queries as functions to my SessionBean through facade this are the results I get

    /** <code>select o.thememo from Memos o where o.sourceid = :recid and o.memotyp = 101</code> */

    @TransactionAttribute(TransactionAttributeType.NOT_SUPPORTED)

    public List<Byte> getMemosFindPhoto(String recid) {

        return em.createNamedQuery("Memos.findPhoto", Memos.class).setParameter("recid", recid).getResultList();

    }

    /** <code>select 'image/jpeg', o.thememo from Memos o where o.sourceid = :recid and o.memotyp = 101</code> */

    @TransactionAttribute(TransactionAttributeType.NOT_SUPPORTED)

    public List<Object[]> getMemosGetPhoto(String recid) {

        return em.createNamedQuery("Memos.getPhoto", Memos.class).setParameter("recid", recid).getResultList();

    }

The first gives me a List of Bytes and the other a List of Object Array, and the only thing I want to return is the blob as image.

Both returns in my SessionBean are giving errors, 'Incompatible types' but this was generated.

Without those functions, when I try to add the service to my JAXB schema it won't allow it.

What am I doing wrong or what am I missing?

I'm using JDev 12.1.3.0

Thanks

and when I add 'image/jpeg', 'image/jpeg','image/jpeg',

This post has been answered by kdario on Aug 12 2015
Jump to Answer

Comments

kdario
em.createNamedQuery("Memos.findPhoto", Memos.class)

em.createNamedQuery("Memos.getPhoto", Memos.class)

mage/jpeg','image/jpeg',

Well, when you use some api, you first need to read (and understand ) docs for it.

Here is description for createNamedQuery() with two parameters(note that there is also the same method with only one parameter): https://docs.oracle.com/javaee/6/api/javax/persistence/EntityManager.html#createNamedQuery%28java.lang.String,%20java.la…

Dario

DLopez

Hi Dario, thk for your reply but I'm not following.

What does the createNamedQuery as to do with it?

That part of code was generated when I added them to my SessionBean

kdario

That part of code was generated when I added them to my SessionBean

Are these queries also generated?

  1. @NamedQuery(name = "Memos.findPhoto", query = "select o.thememo from Memos o where o.sourceid = :recid and o.memotyp = 101"), 
  2. @NamedQuery(name = "Memos.getPhoto", query = "select 'image/jpeg', o.thememo from Memos o where o.sourceid = :recid and o.memotyp = 101"

Like I said in previous reply, read docs for createNamedQuery(), then analyze your queries(hint: look at select clause) and you will find issue.

Dario

DLopez

I get it Dario, I cannot add that 'image/jpeg', in the query, so both queries I have presented are wrong.

In this case I can only create a function that use a query to get the row where the image is and return that image.

Since I'm working with byte[], my service function will have to treat that data and convert it so it can be read as as image.

Am I correct, thinking this way?

kdario

So why you don't use createdNamedQuery() with only one parameter?

Something like this: http://stackoverflow.com/questions/5498391/how-to-download-a-file-stored-in-a-database-with-jsf-2-0

Dario

DLopez

I can use it, but in my class that attribute is recognized as a byte[] and when I add that 'query' to my SessionBean it will create a function that returns a List<Byte>. I can't even return the array that getTheMemo will return.

This brings me another question, how can I define in the query, if possible, that the return of it is a class object or a type like string or something else?

kdario

I'm not sure that I understand your question.

You can define your own @NamedQuery then define your own java method to invoke that query and return byte[] or whatever you want.

(like downloadGarbage(Long id) function in referred stack overflow link)


Dario

DLopez

What you are saying, if I understand it correctly is that I don't have to define the functions that call the queries through Session bean facade options.

I create those references by hand in the session bean and interface and it won't establish a 'direct' connection between them.

This way I can control everything.

kdario
Answer

Well, you can create new named queries or change existing, whatever fits your use case.

For example, you can change

@NamedQuery(name = "Memos.findPhoto", query = "select o.thememo from Memos o where o.sourceid = :recid and o.memotyp = 101"), 

to:

@NamedQuery(name = "Memos.findPhoto", query = "select o from Memos o where o.sourceid = :recid and o.memotyp = 101"), 

And then use strongly typed named query (em.createNamedQuery("Memos.findPhoto", Memos.class)) to map result to your Memos entity,

Or you can use @NamedQuery which returns only your image(but then you need to use createNamedQuery() with one parameter).


After that, you can add new method to your interface(or modify existing)

etc.


Dario

Marked as Answer by DLopez · Sep 27 2020
DLopez

Thanks Dario, it works.

When I was adding the service to my client, which was a little bit tricky, I encountered a post referring streamed and non-streamed.

byte[] imageData = SessionBean.getPhoto(recid);

// uncomment line below to send non-streamed

//return Response.ok(imageData).build();

// uncomment line below to send streamed

return Response.ok(new ByteArrayInputStream(imageData)).build();

I tried to find something that could explain the difference between them but i didn't quite understand.

Which one is better or in which situations?

Thanks

kdario

You already have complete content retrieved as byte array on the server so this is probably irrelevant.

Streaming is good if you have large file(because you will not load whole file to server memory) or for video streams(because there is no need to show all content at once).

If you want to effectively use streaming, you need to retrieve data from database as stream, and then pass this stream to http response.

Dario

1 - 11
Locked Post
New comments cannot be posted to this locked post.

Post Details

Locked on Sep 11 2015
Added on Aug 11 2015
11 comments
1,246 views