Forum Stats

  • 3,759,060 Users
  • 2,251,495 Discussions
  • 7,870,477 Comments

Discussions

EJB with Rest service to return a blob

DLopez
DLopez Member Posts: 278
edited Aug 14, 2015 9:30AM in JDeveloper and ADF

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',

Best Answer

  • kdario
    kdario Member Posts: 3,519 Silver Crown
    edited Aug 12, 2015 1:22PM Accepted 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

«1

Answers

  • kdario
    kdario Member Posts: 3,519 Silver Crown
    edited Aug 11, 2015 9:31AM
    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
    DLopez Member Posts: 278
    edited Aug 11, 2015 9:53AM

    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
    kdario Member Posts: 3,519 Silver Crown
    edited Aug 11, 2015 9:59AM
    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
    DLopez Member Posts: 278
    edited Aug 12, 2015 11:46AM

    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
    kdario Member Posts: 3,519 Silver Crown
    edited Aug 12, 2015 12:16PM

    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
    DLopez Member Posts: 278
    edited Aug 12, 2015 12:39PM

    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
    kdario Member Posts: 3,519 Silver Crown
    edited Aug 12, 2015 12:47PM

    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 <span class="pln">downloadGarbage</span><span class="pun">(</span><span class="typ">Long</span><span class="pln"> id</span><span class="pun">)</span><span class="pln"></span> function in referred stack overflow link)


    Dario

  • DLopez
    DLopez Member Posts: 278
    edited Aug 12, 2015 1:13PM

    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
    kdario Member Posts: 3,519 Silver Crown
    edited Aug 12, 2015 1:22PM Accepted 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

  • DLopez
    DLopez Member Posts: 278
    edited Aug 14, 2015 9:20AM

    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

This discussion has been closed.