Wednesday, September 8, 2010

Store Images in BLOB in Oracle ADF

Hi,
In this post we will see how to store images in BLOB type database column instead of server OS. This post also shows how to read images later from BLOB column using Image servlet.

Download the sample code

Summary of steps as follows:

1) Create table with BLOB column.

2) Create Business Components as usual make sure the type is BlobDomain is selected.

3) Create Managed Bean which process image to store in BLOB  (request scope level)

4) Create Image Servlet to read Images from database table.

Details in this video.





Happy JDeveloping,
Baig

66 comments:

  1. Hi,

    I'm attempting to do the same thing as your example, only on a MySQL database.

    Obviously, I cannot use BlobDomain. Do you have any idea of how to do this in MySQL.

    After some efforts, I was able to save a Blob to my table, but upon loading it again, I was getting an Index out of bounds exception every time it was trying to cast to a java.sql.Blob.

    If you have any suggestions, I would greatly appreciate it. It doesn't make sense to me that it should be that much more difficult than the way you were able to do it.

    Thanks,

    Joel

    ReplyDelete
  2. Hi! Your tutorial is very good. But what I need to do if one record can contain multiple images? And what to do I I want to store not only images but also documents. I can upload document with same code, but how can acces it from form?

    May be if You can You can made tutorial to explain may questions...

    Best regards, Kristaps, waiting for Your response!

    ReplyDelete
  3. Hi,

    I think you can store documents with the same code only you need to change approach to retriev the files.

    Check this blog entry might help you http://kuba.zilp.pl/?id=841

    ReplyDelete
  4. @Rolls

    I think same code should work for MySQL as well. BlobDomain automatically maps to Blob in oracle same should go for MySQL.

    ReplyDelete
  5. Hi, Baig! Can You say which way is the best, store files in DB or in server?

    Best regards, Kristaps

    ReplyDelete
  6. Hi Kristaps,

    In my opinions its depends on your requirement if you wants portability then database is right choice. if you can afford storage then operating system could be efficient but you have to include it in backup strategy as well.

    ReplyDelete
  7. how we can download an image from a blob filed.
    and in your sample how can i show my path of file in a text box

    ReplyDelete
  8. Hi Baig,

    Very useful blog. I want to achieve similar to what Kristaps is looking for - i.e. storing multiple images for a record. I'm unable to access blog entry http://kuba.zilp.pl/?id=841.

    I have 3 tables, one for employee, one for attachments and 3rd one contains mapping between employee id and attachment id. When I upload an image I want to add a row in attachments table and in the mapping table.
    Any suggestions how I can do that?

    Thanks,
    Gaurish

    ReplyDelete
  9. Hi Baig,

    I executed your application on my local environment with no row existing in the table. I faced null pointer exception on the following line of code in UploadBean.java since row comes as null.

    DCIteratorBinding iter = bindingsImpl.findIteratorBinding("HrImageIterator");
    Row row = iter.getCurrentRow();
    row.setAttribute("ImageBlob", createBlobDomain(myfile));


    It executed fine after I manually inserted a row in table.

    Can you please let me know how we can fix the code if there is no existing row in the table?

    Thanks,
    Gaurish

    ReplyDelete
  10. hi gaurish,

    you can check the not null condition before null pointer exception.

    try this

    if (!row == null)
    {
    ....
    }

    i hv out of my jdev so cant test

    ReplyDelete
  11. Hi Baig,

    I followed your example and added more functionality in my application.

    My page is a Page fragment than include a bounded task flow.
    Everythink works fine but when i update the image the refresh of image component don´t work.
    If i insert a new image the refresh of image component works fine.

    In a normal page(no page fragment) the refresh works fine.

    Any suggestions.

    Thanks,

    DV

    ReplyDelete
  12. Hi,

    What is the scope of managed bean?

    In this case i think you should use BackingBean scope for managed bean.

    I will try your use case then let you know.

    ZB

    ReplyDelete
  13. Hi,

    The scope was request following your example.

    I changed the scope to managedBean but the result is the same.

    Reloading the page the new image appears.

    Thanks

    DV

    ReplyDelete
  14. Hi DV,

    Are you pointing Partial submit and Partial triggers property to correct component ?

    ReplyDelete
  15. Hi,

    Yes,

    Partial summit at Button(for proces upload BB) and Partial triggers at image pointing to button.

    I reproduced with your example.

    Is doing the same think.

    Thanks

    ReplyDelete
  16. If possible send me your application at
    zeeshan dot baig82 at gmail dot com

    i will try myself as well.

    ZB

    ReplyDelete
  17. Thank you your example is very much helpfull
    Could you pls guide me how to store images if the column is long raw!!

    ReplyDelete
  18. Hi Prasad,

    Long-Raw data type is not recommended and not a best way to store images. use BLOB you will get lot of performance benefits.

    ZB

    ReplyDelete
  19. Very helpful tutorial.I want to upload and download videos.
    I tried to upload videos by this tutorial, when I clicked on SaveImage button I got following error

    Warning: The file upload failed.
    The file could not be uploaded because it is too large.
    How I can solve it

    or suggest some other tutorial link for uploading videos in blob column

    ReplyDelete
  20. Hi Arshad,

    Set the following parameters in web.xml

    http://docs.oracle.com/cd/B25221_05/web.1013/e18745/devguide/fileUpload.html#Configuration

    ReplyDelete
  21. hi Baig,
    thanks for this tutorial and for the others :)
    i follow this samples, the image was stored in the blob i check the space using dbms_lob, but the image doesn't displayed on the page. i use a servlet showImage and set the value of blob source : /ShowImage?id=#{bindings.EmployeeId.inputValue}

    Could you pls guide me how to resolve my pb
    thanks

    ReplyDelete
    Replies
    1. Hi Fakhri,

      Please check the log files to identify the error. I think you are not able to store the file to BLOB.

      ZB

      Delete
    2. hi Baig,
      I did it, the pb was /ShowImage?id... must be /showimage?id...

      other things where is the location of the log files error
      thanks

      Delete
    3. Yes Java is case sensitive language if you have created your servlet with showImage you have to use showImage not ShowImage or showimage.

      You can see the Errors inside Jdeveloper under Messages Log. Choose View > Log if you dont see that window.

      On server it is usually under your weblogic domain/servers/managed_severs/log directory

      Delete
    4. hi baig,
      I tested the application using jsf page and work good, but when i used a bounded TaskFlow I found a error when i fire the methode setImage() : java.lang.NullPointerException, I debug the code and i find that it does not pointing to the file, but the inputfile value =#{viewScope.UploadImage.file} . I modify the scope of the managedBean UploadImage to BackingBean, pageFlow,.. but the error still exist.

      Could you pls guide me how to resolve my pb
      thanks

      Delete
    5. Make sure you have registered the bean in task flow as well.

      ZB

      Delete
    6. Hi ZeeShan,
      Finally I found the origin of the error : java.lang.NullPointerException when i pressed the button to setImage method, it was the main page .jsf and not .jspx, so when i replace my main page .jspx it works fine :)
      so plz can you explain the difference between jsf and jspx and why there is error when we use jsf page

      thanks

      Delete
    7. I found the solution :
      I have to set the property on the master page form element :


      because it's not possible to use form tag in jsff page so we need to put it in the master page

      Fakhri

      Delete
    8. yes Page fragment should not have af:form tag

      Which property you set ?

      ZB

      Delete
  22. Hi Zeeshan,

    I got same problem . Null Pointer Exception when clicked Save Image


    It is not picking the value. I tried putting debug statements.
    It row iter is taking ImageId and Image Description however some issue with Blob Image.

    Please let me know what could have missed ?

    Thanks,
    Jit

    ReplyDelete
    Replies
    1. Hi,

      Can't help without looking at your code.

      ZB

      Delete
    2. may be your main page was jsf try to replace it with an jspx page and try

      Delete
    3. finally i found the cause of Null Pointer Exception when clicked Save Image,
      this error appear when you use a fragmented page jsff in jsf main page. but when you use jsff page referenced in jspx the error will not appear, i tested 3 scenario :
      main page jspx => works fine
      main page jspx and dynamic region or region reference to jsff page ==> works fine
      main page jsf without dynamic region or region reference to jsff page ==> works fine
      main page jsf and dynamic or normal region reference to jsff ==> Null Pointer Exception when clicked Save Image

      FK

      Delete
    4. Hi,

      jspx is default extension for JSF pages in JDEV R1 supporting JSF 1.2.

      From JDEV R2 the default page extension is .jsf which support JSF 2.0

      Hope it helps,
      ZB

      Delete
    5. This comment has been removed by a blog administrator.

      Delete
  23. hey Baig,
    Very great tutorial and i already implemented it successfully. but i have one problem facing me, my table have two blob image columns that i need to show. how can i show two columns? your help is urgently needed.....thanks in advance :)

    ReplyDelete
    Replies
    1. Hi,

      You can do the same thing what you did with the first column. There is no special step for that.

      ZB

      Delete
    2. In a new http servlet or in the same one?
      thnx for replying

      Delete
    3. You can pass additional parameter to same servlet if you read the code i am creating a parameter id
      String imageId = request.getParameter("id");

      then selecting the value from database and setting the value of this parameter

      PreparedStatement statement =
      conn.prepareStatement("SELECT image_id, image_blob " +
      "FROM hr_image_table " +
      "WHERE image_id = ?");
      statement.setInt(1, new Integer(imageId));

      in the end retrieving the value
      Blob blob = rs.getBlob("IMAGE_BLOB");

      so you need to add additional parameter in the same servlet and set the source of image component in JSF page




      Hope it helps,
      ZB

      Delete
    4. The thing is my table holds details of some companies such as company id, address and 2 blob columns one that holds the company logo and another one that holds the company's CEO picture.
      so for each company i need to show these 2 images and
      that is where i faced my problem because its only one parameter which is the company ID.
      "Select company id, president logo, company logo where company id= ?"

      I really appreciate your help

      Delete
    5. Yes my bad regarding ID. (typical morning response)
      try to add another column like

      Blob blob = rs.getBlob("COMPANY_LOGO");

      also check this link https://forums.oracle.com/forums/thread.jspa?messageID=1884382

      Delete
  24. Here its afternoon:)
    I tried using
    Blob blob = rs.getBlob("COMPANY_LOGO")
    Blob blob2 = rs.getBlob("PRESIDENTS_PHOTO")

    but i dont know how to call each blob image to my jspx page
    using the /showimage?id=#{bindings.company_id.inputvalue}
    it only shows one image in both.



    ReplyDelete
  25. Hi,
    this is great tutorial. But I have a problem with image uploading. My form is placed into the dynamic region. When I push the "upload" button, the "request" changes the fragment site.
    Please help!
    (sorry for my english)

    ReplyDelete
    Replies
    1. Hi,

      What do you mean my fragment site ? also make sure you have set the useUploaded property to true on the FORM where your page fragment is.

      ZB

      Delete
    2. Hi,

      1)

      2) fragment site - I have
      file.jsff
      - Panel Tabbed
      - Show detail item1
      - Show detail item2
      - FORM
      - upload button

      When I push the button, "request" switches from Show detail Item2 to Show detail item2.
      => FORM becomes empty

      Delete
  26. Hi Zeeshan Baig,
    Thanks for the tutorial. I was able to load and retrieve images from the database successfully. But, when there is no image associated with the current record, I see a red 'X' mark in the image placeholder. Can I set it up to display a default image if BLOB is empty? OR leave the field empty with out displaying 'X' mark.

    Thanks

    ReplyDelete
    Replies
    1. Hi,

      There are lot of ways to do this. You can check the servlet if it returns null then display some other image. also you can take a look at ADF switch component.

      Zeeshan

      Delete
    2. Thanks Zeeshan Baig. I have looked at the af:Swticher component and am working on it to implement it. I am also wondering about another way which is to set the rendered component. I can know if the image is not available from the doGET method of ImageServlet. How do I use it in setting the render property for the image item to false? Appreciate your help.

      Thanks
      Ashok

      Delete
    3. Hi,
      you can point to some default image e.g. 'noimage.jpg' and pack that image with the application. In this case return noimage.jpg from servlet as source of image.

      Zeeshan

      Delete
  27. Hello Zeeshan Baig,
    I'm getting error "Invalid empty lob operation
    java.sql.SQLException: Invalid empty lob operation"
    Can You Please help me!?
    Thanks
    Ian

    ReplyDelete
  28. Hi,

    I have other problem: I've got a record in the table. I upload an image and press 'Upload' button - NullPointerException. After debugging I found that setFile setter is never invoked (when I launched your App, the setter was invoked). Where is the problem?

    Thanks,
    Michal

    ReplyDelete
  29. Hi,

    I have to upload the files into one of the server path.Could you please share any information on this.

    Thanks,
    Venkat.

    ReplyDelete
    Replies
    1. Hi Venkat,

      Whatever path you will set in web.xml it will upload there on server.



      oracle.adf.view.faces.UPLOAD_TEMP_DIR

      /tmp/ADFUploads/


      Check this link for more info http://docs.oracle.com/cd/B25221_05/web.1013/e18745/devguide/fileUpload.html#Configuration

      Regards,
      Zeeshan

      Delete
  30. Hi Zeeshan,
    i'm trying to upload images into my Oracle database and retrieve them on ADF forms. I use Jdeveloper 12c and don't know how to do it.

    Could you help me please? I'm a jdeveloper beginner.

    Thanks!

    ReplyDelete
    Replies
    1. This post does exactly that.

      Zeeshan

      Delete
  31. I tried using your Sample with my Jdeveloper 12c. But it doesn't work correctly. I cannot execute it. There are some components like commandbutton that do not exist anymore in the JDeveloper 12c version!

    Please help me!

    Best regards,

    ReplyDelete
  32. Dear Zeeshan,
    I found a conversation between you and person DV,
    I am also facing the same refresh issue,
    I am uploading image and displaying it after commit in the adf form,
    first time I am able to display the uploaded image, but while I try to upload another image or edit the same record, the uploaded image is not displayed, but it will be displayed after i run the screen again.
    Please provide any useful inputs.

    Thanks in Advance
    Santhosh

    ReplyDelete
  33. Dear Zeeshan,
    I found a conversation between you and person DV,
    I am also facing the same refresh issue,
    I am uploading image and displaying it after commit in the adf form,
    first time I am able to display the uploaded image, but while I try to upload another image or edit the same record, the uploaded image is not displayed, but it will be displayed after i run the screen again.
    Please provide any useful inputs.

    Thanks in Advance
    Santhosh

    ReplyDelete
  34. Hi Zeeshan,

    As you suggested I have used oracle.adf.view.faces.UPLOAD_TEMP_DIR.In web.xml I have added below piese of code.



    Parent directory location of SRDemo fileuploads
    SRDemo.FILE_UPLOADS_DIR
    D:/Docs


    I have initialized the the parameter in the bean and it is creating the blank files.I have used below code to copy the files,

    public String doUpload()
    {
    InputStream in;
    FileOutputStream out;
    UploadedFile file1=getFile();
    System.out.println(file1.getFilename());
    long lon = file1.getLength();
    System.out.println("lenght of the file"+Long.toString(lon));
    System.out.println("Outside file");
    byte[] buffer = new byte[1024];

    String fileUploadLoc =
    FacesContext.getCurrentInstance().getExternalContext().
    getInitParameter("SRDemo.FILE_UPLOADS_DIR");
    System.out.println(fileUploadLoc);

    try {
    System.out.println("Inside Try");
    System.out.println(file1.getFilename());
    System.out.println(fileUploadLoc);


    out = new FileOutputStream(fileUploadLoc + "/" + file1.getFilename());
    System.out.println(fileUploadLoc + "/" + file1.getFilename());
    in = file1.getInputStream();

    in.close();
    out.close();
    } catch (IOException e) {
    e.printStackTrace();

    }
    System.out.println(file1.getFilename());
    System.out.println(file1.getContentType());
    return "Success";
    }

    This method is getting executed,but blank file is getting created in the specified folder.

    Please help me on this.

    Thanks,
    Venkat.

    ReplyDelete
  35. Hi Zeeshan,

    As continuation to the above requirement,once we upload the file we need to display the list of files that are existing in that uploaded folder.

    Could you please let me know,how to achieve this.

    Regards,
    Venkat.

    ReplyDelete
    Replies
    1. Check this blog it got more detail step by step details you to follow http://tompeez.wordpress.com/2011/11/26/jdev11-1-2-1-0-handling-imagesfiles-in-adf-part-2/

      for List of values either you can store the uploaded files in the database table or use Java APIs to query the content of the folder.

      Zeeshan

      Delete
  36. Hi zeeshan,
    Image refresh is not working in page fragment when i upload ,only when reloading it updates the image whereas it works fine in a jsf page .pleae me help me

    ReplyDelete
  37. Hi zeeshan,

    My page fragment doesnot get refreshed when i upload image .but where as jsf page works fine .image getting refreshed when i upload.Please help me

    ReplyDelete
  38. javax.naming.NameNotFoundException: While trying to look up comp/env/jdbc/HrXEDS in /app/webapp/BlobImageExample-ViewController-context-root/1101515126.; remaining name 'comp/env/jdbc/HrXEDS'

    ReplyDelete
    Replies
    1. Hi,

      Change the database connection settings are per your environment. I have modified the tables to add blob.

      Zeeshan

      Delete