Home » Java » Enterprise Java » Working with the Array Data Type in a Table

About Eugene Fedorenko

Working with the Array Data Type in a Table

In this post I would like to follow up on my previous article about Oracle collection data types and I am going to focus on working with oracle.jbo.domain.Array attributes in af:table component.

So, in my database I have the following SQL type:

 
 
 
 
 

create or replace type varchar2_array_type as table of varchar2(200)  

And I’ve got the following table:

create table testarray (
SomeField Number,
ArrValue VARCHAR2_ARRAY_TYPE)
nested table ArrValue store as arrvalue_tab return as value;

There is an entity in ADF BC model which is based on the testarray table:

Screen Shot 2014-04-25 at 5.06.18 PM

The data type of the attribute Arrvalue is oracle.jbo.domain.Array. 

There is a corresponding attribute binding in the binding container:

    <attributeValues IterBinding="VTestarrayIterator" id="Arrvalue">
      <AttrNames>
        <Item Value="Arrvalue"/>
      </AttrNames>
    </attributeValues>

The easiest way to display the value of this attribute could be like this:

<af:table value="#{bindings.Arrvalue.inputValue.array}" var="row" 
          id="t1">
   <af:column sortable="false" headerText="Array Values" id="c1">
      <af:inputText value="#{row}" id="ot3"/>             
   </af:column>
</af:table>

And the result looks pretty nice:

Screen Shot 2014-04-25 at 5.35.38 PM

The only problem with this approach is that the table is not updatable. It is read only one.

The EL expression “#{bindings.Arrvalue.inputValue.array}” is going to invoke the method oracle.jbo.domain.Array.getArray() which returns an immutable Object[] array and all modifications to this array will be lost.

If we need to be able to update the data in the table, we’ve got to do the following:

  1. Make a copy of the bindings.Arrvalue.inputValue.array
  2. Set this copy as table’s value
  3. At the Update Model Values phase wrap the copy back into oracle.jbo.domain.Array and put it to the Arrvalue.inputValue.

So, we are going to make a copy and keep it in a request scope managed bean:

private Object[] array = null;

private Object[] createArray() {
  JUCtrlValueBinding dcb = getArrayCtrlBinding();
  if (dcb!=null){
      Array arr = (Array) dcb.getInputValue();
      if (arr!=null) {
          array = arr.getArray();
      }          
  }
  return array;
}


public void setArray(Object[] array) {
    this.array = array;
}

public Object[] getArray() {
    return (array == null ? createArray() : array);
}

    
private JUCtrlValueBinding getArrayCtrlBinding() {
  BindingContext bc = BindingContext.getCurrent();
  DCBindingContainer binding = (DCBindingContainer) bc.getCurrentBindingsEntry();
  return (JUCtrlValueBinding ) binding.findCtrlBinding("Arrvalue");
}

When it comes to using this copy as table’s value, we can do the following:

  <af:table value="#{TheBean.array}" var="row" 
            id="t1"
            varStatus="status">
    <af:column sortable="false" headerText="Array Values" id="c1">
       <af:inputText value="#{TheBean.array[status.index]}" id="ot3"/>             
    </af:column>
  </af:table>

Note, that we didn’t use just #{row} as inputText’s value. It wouldn’t work, since #{row} would just return an immutable String. Instead of that we used the varStatus table attribute. The EL expression #{TheBean.array[status.index]} makes the framework able to call a corresponding setter method at the Update Model Values phase, so all modifications made in the table will be saved to the TheBean.array.

The last step is to put TheBean.array back into the attribute value at the Update Model Values phase. We can use a fake invisible inputText for that purpose:

<af:inputText value="#{TheBean.dummy}" 
              visible="false" 
              converter="EmptyConverter"
              id="it2"/>

This input text should be placed below the table on a page. The beauty of this approach is that the framework will try to update the inputText value on each request. So, the setter method TheBean.setDummy(String dummy) will be invoked on each request at the Update Model Values phase right after the table values have been saved to the TheBean.array. And at this moment we’re going to wrap the array into oracle.jbo.domain.Array and put it back to the Arrvalue.inputValue:

public void setDummy(String dummy) {
  getArrayCtrlBinding().setInputValue(new Array(array));   
  array = null;
}

The secret of this dummy inputText is hidden in the EmptyConverter:

public class EmptyConverter implements Converter {
 public Object getAsObject(FacesContext facesContext,
                           UIComponent uIComponent, String string) {
     return null;
 }

 public String getAsString(FacesContext facesContext,
                           UIComponent uIComponent, Object object) {
     return null;
 }
}

It emulates that null value has been submitted for this component with the request. On the other hand, the dummy getter always returns a not null value:

 public String getDummy() {
    return DUMMY;
 }

So, the framework has no option, but to invoke the setDummy method at the Update Model Values phase.

The sample application for this post requires JDeveloper 11.1.1.7.

That’s it!

Reference: Working with the Array Data Type in a Table from our JCG partner Eugene Fedorenko at the ADF Practice blog.

Do you want to know how to develop your skillset to become a Java Rockstar?

Subscribe to our newsletter to start Rocking right now!

To get you started we give you our best selling eBooks for FREE!

1. JPA Mini Book

2. JVM Troubleshooting Guide

3. JUnit Tutorial for Unit Testing

4. Java Annotations Tutorial

5. Java Interview Questions

6. Spring Interview Questions

7. Android UI Design

and many more ....

Leave a Reply

Your email address will not be published. Required fields are marked *

*


four − 4 =

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

Do you want to know how to develop your skillset and become a ...

Subscribe to our newsletter to start Rocking right now!

To get you started we give you our best selling eBooks for FREE!
Get ready to Rock!
To download the books, please verify your email address by following the instructions found on the email we just sent you.

THANK YOU!

Close