Saturday, June 23, 2007

Create, Edit and Delete operations in Master-Detail af:table components

It seems, my previous post about Create, Edit and Delete operations in ADF Faces af:table component is popular, I have received comments and questions from JDeveloper/ADF developers. One of the most interesting questions was about how to use the same functionality for Master-Detail, when both are based on af:table component. I have decided to implement Create/Edit/Delete functionality for Master-Detail case and to show how it works in Oracle ADF - EditableMasterDetailTable.zip.

Business logic is simple - relation between Countries and Locations entities from standard HR schema is implemented. Countries is for Master, and Locations for Detail. Master-Detail screen:


When row in Master table is selected, Detail table is updated automatically. It happens, because Oracle ADF provides Partial Page Rendering (PPR) functionality. Developed sample allows to manage Master record and at the same time dependent Detail records can be managed also.

Create functionality in Master table:


When record in Master table is saved, it becomes possible to add dependent records in Detail table:

54 comments:

Anonymous said...

thanks for posting this blog :):)

Sandra Muller said...

Hi Andrejus,

Did you know that JHeadstart can generate af:table components in which you can update or delete every row, and insert new rows? You can see an example picture at this post on the JHeadstart blog.
It also works with master-detail tables.

kind regards,
Sandra Muller

Andrejus Baranovskis said...

Hi Sandra,

Thanks for suggestion. In fact, I know that JHeadstart can generate af:table components with additional operations. I'm planning to review this in my future posts.

Regards,
Andrejus

Vijaya said...

Hi Andrejus
I have seen the application which you discuused. Ihavesimilar application. But I could not understand from which VO you have dragged those 2 tables in main.jspx. Is it from the countriesView1 which has the Master-Detail relationship.
Please do reply ASAP
With Regards,
Vijaya.

Andrejus Baranovskis said...

Hi Vijaya,

Yes, you are right. Master-Detail relationship is created by dragging LocationsView2 which is available in CountriesView1.

Regards,
Andrejus

Vijaya said...

Hi Andrejus,
Thanks for the reply. I have one more problem. when ever I say create in the master table, the details table shows the records from the database which should not happen.
Please let me know how to do this.

Andrejus Baranovskis said...

Hi,

But, in my sample when you create new Master record, Detail table is empty. You should check it. Please, inform me about your progress.

Regards,
Andrejus

Vijaya said...

Hi
My application is little different from yours. I have 2 pages. One Search screen and another for Create/updation.
In the Search Page ,I have a create Master/detail Button , clicking on which takes to the Create Page.
In that page ,I have taken Master Table as Creation form and details as Editable Table. So the creation form is empty ,but the detail table shows the records.
How to make details table empty intially?

Andrejus Baranovskis said...

Hi,

I understood your problem. It's because you are trying to show detail table for non existing master record, that will be created.

I will look into this, and will try to provide some info during week.

Regards,
Andrejus

Andrejus Baranovskis said...

Hi Vijaya,

I have developed a sample for your case. Can send it to you, just drop me an email.

Regards,
Andrejus

Gary said...

ok thanks I will try that. Now if I could only get a button to actually show up!!!

Anonymous said...

Hello Andrejus,
unfortunately I'm a new ADF developer and my first task is to implement a similar functionality of yours Master-Detail CRUD example. I have studied a lot your code, I'm almost done but I can not understand how the create button is working. In my example it doesn't create a new row for insert.
I don't know what I miss.
A short description of what really happens between page and backing bean or anything else should be great.

Thanks A Lot
Dimitris

Andrejus Baranovskis said...

Hi Dimitris,

Most probably you will get needed info in this my blog post - Creating new row using CreateInsert operation. It describes how implement Create functionality in ADF, I have used the same method for create here.

Regards,
Andrejus

Pradeep Cahubey said...

Hi Andrejus,
I gone through the sample which you have given but i am not able to implement ActionListener for "Edit" button.My problem is to perform "Edit","Update","Delete" operation in a single table. I have not created backing bean. Please tell me how to achieve it. Thanks in Advance

Pradeep Cahubey said...

Hi Andrejus,
Thanks a lot I did the assignment properly, now i can do what i wanted to. I have a new problem I have to perform search based on keyword. Once the button is clicked data should be populated in the same table.Please Help me.
Thanks in Advance

Andrejus Baranovskis said...

Hi,

Can you explain your case little bit more?

Thanks,
Andrejus

Pradeep Cahubey said...

Hi Andrejus,
The scene is like this, I have a ADf table where I am displaying data from a Master Table in the Database. Now I have to provide a facility to Administrator to search a particular or list of related record from the table.I have to give him facility to add record, update record and delete record from the searched data also. Please give some idea.Hope you understand the problem.

Anonymous said...

Hi Andrejus,
thanks a lot for your instant answer, I managed to solve it. You were right.

Dimitris

Pradeep Cahubey said...

Hi Andrejus,
I am able to make a row Editable when "EDIT" button is Clicked but the new value is not being saved When Clicking the "Save" Button.
Here I think we are updating the Table is it possible to overwrite the values from "Save" button which is actually a commit operation ?? Please Help me I am not able to solve this problem...

Andrejus Baranovskis said...

Hi,

You should drag and drop on Save button, from Data Control - Commit operation. It should work, when you will done this.

Regards,
Andrejus

Pradeep Cahubey said...

Hi Andrejus,
I had followed all the steps but still "EDIT"+"SAVE" is not working. To accomplish this Now, I have written a Custom Method in Application Module Class. That Method Will take two parameters, Code and Name.I have binded this method as command operation. But here, My problem is I am not getting the passed parameters in the Custom Method. The Code is Given Below :

public void updateSearch(String districtCode, String districtName) {
System.out.println("CODE==>"+districtCode);
System.out.println("Name==>"+districtName);
/* DBTransaction dbt=getDBTransaction();
//Key key=(Key)districtCode;
EntityDefImpl searchDef = DistMstImpl.getDefinitionObject();
DistMstImpl newProduct =
(DistMstImpl)searchDef.createBlankInstance2(dbt);
newProduct.setDistrictName(districtName);

//newProduct.setDescription(description);
try
{
//getDBTransaction().commit();
dbt.commit();
}
catch (JboException ex)
{
dbt.rollback();
throw ex;
}
//DBSequence newIdAssigned = newProduct.getProdId();
//return newIdAssigned.getSequenceNumber().longValue();
//return newProduct;*/
}

I have Commented most of the lines because this was not working. Please tell me "How can i take the Values from bind variables " and how to store them in the database with the help of Custom methods.

Andrejus Baranovskis said...

Hi,

You can find needed technique in this my post - Invoking Create method programmatically.

In this sample I'm invoking method in Application Module to create new row.

Regards,
Andrejus

Pradeep Cahubey said...

Hi Andrejus,
How should i write the custome method for Update operation. Assuming that user first, will make the row of the table editable and supply the new value and clicks the "update" Button.The Update Button is the button for which I have to write the Code.

thanks in Advance

Andrejus Baranovskis said...

Hi,

If your custom code is related to ViewController logic, you can implement it in Backing Bean associated with the page. If it is related with Model, you can implement new function in Application Module class and expose it to ViewController through client interface.

Regards,
Andrejus

Sudha said...

Hi,

I've created a Master/Detail Form using invoice, product tables in ADFBC JSPX. I want to update total field in Invoice Table when i insert or update a row in Product form. How can I acheive this??

Thanks and Regards,

Sudha.

Andrejus Baranovskis said...

Hi Sudha,

You can use something similar I descibed in my recent post - Complex Calculated Values in Oracle ADF af:table Component.

Regards,
Andrejus

Sudha said...

Hi Andrejus,

I've created a procedure to update a Master Table whatever i've entered in details form, now i want to refresh the Master View automatically to see the new values when i return my view page from details entry. Procedure is working fine and in the Master Table, field also getting updated, but i'm not able to see the result in my view page. How to refresh the data?

Thanks in advance

Sudha.

Andrejus Baranovskis said...

Sudha,

It depends on your case, but you can try two things that always work:

1. To invoke Execute action

Or

2. To use page refresh method:

protected void refreshCurrentPage() {
FacesContext context = FacesContext.getCurrentInstance();
String currentView = context.getViewRoot().getViewId();
ViewHandler vh = context.getApplication().getViewHandler();
UIViewRoot x = vh.createView(context, currentView);
context.setViewRoot(x);
}

Hope it will work.

Regards,
Andrejus

Neetha said...

Hi Andrejus,
I have a similar issue like Vijaya has mentioned,
I have taken Master Table as Creation form and details as Editable Table. The creation form is empty ,but the detail table shows the records.
Can you please suggest, how to show the details empty.
Thanks
DN

Andrejus Baranovskis said...

Hi Neetha,

You can just drop me an email. I will send you that application I developed for Vijaya.

Regards,
Andrejus

Ans said...

Hi Andrejus,
I have created a Master-Detail af:table components as u said
It is working perfectly for me.
But I have another requirement.
When I create and save a new row in Details table,I also want to insert
these values into another independent table also.
Please let me know how to do this.
Thanks
ANS

Andrejus Baranovskis said...

Hi Ans,

You can achieve this with those steps:

1. Generate Entity Object Java class with Data Manipulation Methods option included for Detail entity

2. Look for doDML(...) method in newly generated class, this method is executed during Create (with code 1 for Create operation)

3. In doDML method you can access all attributes from Detail entity and using code available in my blog post - Invoking Create method programmatically create row in this not dependent table. Just reuse code from createCountry(...) method.

Regards,
Andrejus

siva said...

Hi Andrejus,
I am able to make a row Editable when "EDIT" button is Clicked but the new value is not being saved When Clicking the "Save" Button.
Here I think we are updating the Table is it possible to overwrite the values from "Save" button which is actually a commit operation ?? Please Help me I am not able to solve this problem...
........

Andrejus Baranovskis said...

Hi Siva,

Is it in my sample application?

You need to use Commit operation to execute Save functionality.

Regards,
Andrejus

Anonymous said...

Hi Andrejus,
i want to make the application when the user input the countryId (and tab to next field), the apps should query another table for countryName. How to do this ?

Thanks,
Ricky

Andrejus Baranovskis said...

Hi Ricky,

If I understood you correctly, I think you need to enable AutoSubmit on countryId field and declare PartialTriggerring for a table with countryName. So, when countryId value will be provided, table with countryName will be refreshed.

Regards,
Andrejus

Anonymous said...

Hi Andrejus,

I am able to make a row Editable when "EDIT" button is Clicked but the new value is not being saved When Clicking the "Commit" Button.
Actually i draged that commit button form dataCOntrol pallete only(As per your procedure)...

public boolean isEnableEditing()
{
FacesContext ctx = FacesContext.getCurrentInstance();
Application app = ctx.getApplication();
ValueBinding bind = app.createValueBinding("#{row.Pycode}");
String jobId = (String)bind.getValue(ctx);
this.enableEditing = this.getSelectedJobId().equals(jobId);

return this.enableEditing;
}

Andrejus Baranovskis said...

Hi,

Do you have Commit action defined in Page Definition?

Regards,
Andrejus

dieciocho said...

Hi Andrejus, your examples have been very helpful, I want to thank you for providing us with such good code samples. Well I have also got a question for you. I am working on an example in which I have to create new rows. Let´s say I added a new row with the create button and I filled in the correct info for that row. Then, I want to create a new row, so I hit the create button and the new Inputs appear, but I change my mind and I don´t want to add another record. How can I get through the validation that won´t let me submit the changes I have already made (the first insertion)? Is there a way to just remove that last Input row?
If you could help me with that I would really appreciate it

Andrejus Baranovskis said...

Hi,

Its good question, I will check this today evening and will post update.

Regards,
Andrejus

Andrejus Baranovskis said...

Hi,

Create Method Action for Save button and in Backing bean check for empty rows (acquire collection from Iterator). If there will be some empty rows, remove those rows from Iterator. And do commit after that.

Regards,
Andrejus

dieciocho said...

Hi Andrejus, thanks for your update. I associated a method to the action called by the button but the page validation won´t let me get through, and I can´t execute the method. Do you have any ideas on how I can by-pass this validation and let the method take care of all the businees?
Thanks in advance

Andrejus Baranovskis said...

Hi,

Yes, you can set Immediate=True property for Save button. This will by-pass validation.

Regards,
Andrejus

dieciocho said...

Thanks! U Rock!

mm said...

Hi Andrejus,
I got the project from you that you did for Vijaya, I'm not able to figure out what exactly have you done so that when you initially get to the create form for the master table record the detail table below doesn't show any records.
How are you actually doing that?

Sireesha said...

Hi Andrejus,

Thanks for the samples. I have a requirement to join master and detail table with an outer join. In the view link, i tried to detailtableID (+) =:bindValue, but this does not return result as expected. Any ideas on how to achieve the above?
Thanks in advance,
Sireesha

Andrejus Baranovskis said...

Hi,

Have you tried left outer join - detailtableID = :bindValue(+)?

Regards,
Andrej

Sireesha said...

Thanks for your reply.
Yes, I tried 'detailtableID = :bindValue(+)', but I get an error indicating invalid SQL.

Thanks,
Sireesha

Anonymous said...

I'm trying to 'Select and' click the Edit command button to edit a rec in a row. The CountryId in my table is an integer, not a string like in the example, so the <af:setActionListener from="#{row.CountryId}" to="{valueholder.selectedCountryId}> is causing an 'illegal argument' error because it's expecting a string in the 'from'. Don't know how to fix. Please help (and thanks for everything you do).

Andrejus Baranovskis said...

Hi,

Make sure you have updated ValueHolder.java class as well. It declares CountryId as String type, you should update to oracle.jbo.domain.Number.

Regards,
Andrejus

Anonymous said...

You replied:Make sure you have updated ValueHolder.java class as well. It declares CountryId as String type, you should update to oracle.jbo.domain.Number.

Thanks. Making sure ValueHolder.java declared the correct types fixed the problem! You're the best!

yang xingshun said...

I have created a sample like yours and 'edit' & 'delete' & 'save' buttons now work well, but if the location_id is not based on sequence, instead, it based on procedure, eg 'shanghai-01' , 'shanghai-02'. I must get it by using 'createCallableStatement', this one how to do? Thanks!

Anonymous said...

Hi Andrejus,
I want to create a master detail page for order creation,in this page top part will contain af:form to create new order,and bottom of page should contain table to add line item to the new order.Plese help me solve out in solving this problem.

Anonymous said...

Hi Andrejus,

I have a master child scenario where master and child are date effective. Suppose for a particular id if i have two date effective records in master and each date effective record in the master has 2 date effective records in child. Assume that child date effcective records are same for both master date effective records. If i navigate from 2nd date effective master record and update a row in child date effective record, the last update of the first date effective master records is getting updated. But ideally it should update 2nd master date effective record. How can i resolve this issue? The association from master to child is 1-*.