How To Create A Master-Detail Page in ADF 11g

This article builds upon the last article in which we created an updatable Departments list page. In this tutorial, I will expand upon that page by adding a detailed list of Employess in the page that refreshes when the user clicks on a new department row. I will use a partial page refresh so that only the Employee table refreshes, not the entire page.

1. The first thing to do is to create the business components as described in the first tutorial. When you are creating the business components from tables be sure to select Departments and Employees both.

2. Next, create a JSPX page in the ViewController Project.

3. Drag a panelHeader component onto the page and set the text property to “Department Master Detail”.

4. Drag a panelGroupLayout component onto the page and set the alignment property to “Horizontal”.

5. Drag the DepartmentsView1 view instance from the AppModuleDataControl into the panelGroupLayout and choose Tables -> ADF Table from the menu presented to you. In the pop-up I deleted all the fields except for DepartmentId and DepartmentName, select row selection at least from the options on top, in this example I selected all three options, row selection, sort, and filter. Set the id property of the table to “departmentMaster”. You need to make sure that row selection is enabled so that ADF will enable you to select a row in the table and this is the event that will trigger the detail table to refresh. Be sure to Save All.

6. In the AppModuleDataControl, open the DepartmentsView1 node and drag the EmployeesView3 view instance into the panelGroupLayout. Choose Tables -> ADF Read-Only Table and select the columns you want to appear. Also check off at least row selection when creating the table. The key for this is to make sure that you use the view instance that is associated with your “master” view, in this case DepartmentsView1, if you use the other EmployeesView instance, the list of employees will not be in sync with what you select in the Departments table.

7. In the properties of the of the emplyees table set the id to “employeesDetail” and set the partial triggers property, found in the Behavior tab to the id of the master table, i.e. “departmentMaster”. This will tell ADF to refresh the employees table when an event is fired on the departments table. Be sure to Save All.

At this point, you have created a page that will allow you to select a row in Departments thereby refreshing the list of associated employees. We have not yet added any button to actually accomplish anything really useful yet, but we will get to it soon.

One item to note is that this will work as described in Tech Preview 3 of JDeveloper 11g, if you are using Tech Preview 4 to follow this tutorial you will notice that this will only work once or twice before you get a whole mess of validation errors. This is because of a problem with the Technical Preview 4 build that includes a JSF library that isn’t what it was developed with, the discussion is described here. The best fix for now is in the view of the jspx page, switch to the source view and comment out all of the tags that you find in there.

The Dark Side of Frameworks: Part II

My last post about frameworks criticized the Spring JDBC Template construct. I don’t really have anything against Spring in particular, I had just stumbled across the JDBC Template a few days earlier and thought it may help make my point. My point, which I attempted to illustrate by that post, was not that the Spring JDBC Template is useless, it is that frameworks in general, which exist to simplify development of complex technologies, by their nature redirect that complexity somewhere else. Hopefully that new complexity is less than the underlying technology and this is often the case. As an architect/designer/developer you should be aware of that the trade-off exists, what the trade off is going to be and make an informed decision.

1.  Configuration Files

Since I used Spring as an example once before, let’s move on to another one of my other favorite frameworks, Struts. Struts has seemed to have fallen out of favor of late, with many developers now hopping on the JSF bandwagon, including our shop. I had to basically be dragged away from it and forced into JSF. However, even though Struts was my framework of choice for years, it had some problems that really bugged me and are issues that still exist today in many frameworks.

One of the nice things about Java is that you can use a smart IDE and it will spot a lot of careless errors for you, especially simple typos. This is important for someone like me who likes to type fast and can tend to be somewhat careless. What I found with Struts is that I often had problems first setting up projects. For some reason I would always end up with a typo in the struts-config.xml file that would cause it to break when starting my application. Struts was never very good at letting me know what the exact problem was and this never ceased to infuriate me, so much so in fact, that one of our products, Rev, was born out of that frustration because it insured that I wouldn’t have to worry about typos impeding my ability to get an application up and running quickly. I continued to use Struts because it’s benefits outweighed it’s difficulties, it didn’t abstract too much of the HTTP layer so I could still understand what was going on pretty easily.

2.  Too much abstraction

Next, for me, came JSF. I actually only started using it because a project we were working on required a technology that was built upon JSF. Once I started using it, I could appreciate how it’s abstraction of the HTTP layer really made things easier for developers, especially for newbies who didn’t really know much about the HTTP layer. All of this abstraction, however, made it difficult to understand what was happening underneath the covers or exactly how it was happening. Some of the simple Javascript patterns I had been using in Struts to solve some common problems became more difficult. Have you ever looked at the source HTML to a JSF-backed page? It’s not nearly as simple and straight-forward as a page developed from Struts. I am still uncomfortable with the fact that I don’t know exactly how to create a request in JSF to accomplish some things seemingly trivial things, whereas the same things in Struts were really easy.

The other problem that I found as we continued to use the framework was that I could have developers who understood JSF and worked in it really well, but they didn’t understand some of the underlying concepts. When something unexpected happened, they weren’t sure where to look. This would occur when a developer’s first experience with developing web applications was with JSF.

That same problem occurs with any framework, since by their nature they abstract the complexity of some underlying technology. This is all well and good until things break. Obviously, Java itself is an abstraction of underlying technology, do I think we’d all be better off going back to assembly language and programming web applications in that? Of course not, but I think as a developer you should be aware of the pro’s and con’s of the frameworks you use.

You should also take it upon yourself to learn something of the underlying technologies so you aren’t completely clueless. I have interviewed plenty of so-called JSP developers who couldn’t tell me what pieces of code were executed on the server and which on the client, who didn’t understand the underlying concept that once your page was executing in the browser, you weren’t able to execute java commands inside a function in a page. I could understand how a newbie might have some problems with that, but an “experienced” JSP programmer?

3.  The Problem with Fixing #1 and #2

Often, with frameworks that become popular, it’s because the abstraction they provide is more useful than the underlying technology by itself and any new complexities it may introduce, it allows developers to become more productive, hopefully much more productive.

In my opinion, Oracle’s new version of ADF, 11g, is a framework that does just that, but it isn’t without it’s share of compexities either. ADF 11g makes a lot of building a web application declaritive. This may be a good thing, but again, you run into the problem of having to deal with many XML files. Oracle alleviated this problem to a very large degree by creating JDeveloper 11g which can handle building and validating the XML files for you. However, now we have a new problem. There are some mismatches between JDeveloper 11g and ADF 11g. In some cases, just because JDeveloper tells you something is wrong doesn’t mean it is wrong and won’t work. This hints at a larger problem: that both JDeveloper and ADF need to be maintained and released on the same cycles. If one falls behind in respect to changes that were made to the other, the usefulness of the collaboration between the two is degraded.

Also, again in ADF 11g, there is a larger issue. That is, if something acts in an unexpected manner, the developer now needs to understand an additional layer of complexity in order to debug the problem. Often the developer will need to resort to asking the experts via a forum or a bug report. Even if the product is open source and the developer could access the code itself, finding and fixing a problem deep within the framework will obviously detract from the usefulness of the framework itself.

None of these “dark sides”of frameworks are reasons not to use them, I use or have-used all of them, these are just issues that you should be aware of and investigate before using a framework. My “issues” (some may describe these as pet peeves) can be distilled into two main items, 1. Increased abstraction often leads to less understanding and 2. Declarative programming creates its own problems.

Obviously we are going the way of more abstraction, not less.  It will be  a great day when we no longer have to worry about the framework we are using breaking and exposing us to the dirty underbelly of technology behind it all.

</rant>

The Dark Side of Frameworks

Framework seems to be a pretty hot buzzword these days. Not that it hasn’t been for years, but now more and more clients are asking for frameworks for all kinds of things. Frameworks upon frameworks actually.

The most recent example is a client who wanted a framework that would wrap the way you could call stored procedures via JDBC. I was originally against the idea, but being all about customer service, I know when to give up the fight and just roll with it. What one of my developers ended up creating is a framework that wraps JDBC and allows you to save a few lines of code per procedure call, not bad really, but not really enough to change my mind about the whole thing in general.

I could see why they liked the idea, it did hide some of the perceived complexity from the user of the framework, but the reality was it really didn’t do too much more than make sure the close statement was in a finally block and allow the user of the framework to bypass seting all the parameters in a callable statement.

One framework we looked at using instead of creating our own was the Spring framework’s wrapper for JDBC. I don’t want to start a flame war, but honestly, what’s the deal with that monstrosity? What does it actually simplify? From the examples in the documentation I looked at, it seemed simple enough, but that was only because it was doing simple things. When I took a look at called Stored Procedures it didn’t look so simple any more.

Take the example of calling the sysdate() function from Oracle. This is the code for JDBCTemplate:

import java.sql.Types;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

import javax.sql.DataSource;

import org.springframework.jdbc.core.SqlOutParameter;
import org.springframework.jdbc.datasource.*;
import org.springframework.jdbc.object.StoredProcedure;

public class TestStoredProcedure {

    public static void main(String[] args)  {
        TestStoredProcedure t = new TestStoredProcedure();
        t.test();
        System.out.println("Done!");
    }

    void test() {
        DriverManagerDataSource ds = new DriverManagerDataSource();
        ds.setDriverClassName("oracle.jdbc.OracleDriver");
        ds.setUrl("jdbc:oracle:thin:@localhost:1521:mydb");
        ds.setUsername("scott");
        ds.setPassword("tiger");

        MyStoredProcedure sproc = new MyStoredProcedure(ds);
        Map results = sproc.execute();
        printMap(results);
    }

    private class MyStoredProcedure extends StoredProcedure {

        private static final String SQL = "sysdate";

        public MyStoredProcedure(DataSource ds) {
            setDataSource(ds);
            setFunction(true);
            setSql(SQL);
            declareParameter(new SqlOutParameter("date", Types.DATE));
            compile();
        }

        public Map execute() {
            // the ’sysdate’ sproc has no input parameters, so an empty Map is supplied…
            return execute(new HashMap());
        }
    }

    private static void printMap(Map results) {
        for (Iterator it = results.entrySet().iterator(); it.hasNext(); ) {
            System.out.println(it.next());
        }
    }
}

This is as excerpted from Chapter 11 of the Spring Framework Reference Documentation.

I am positive that if I showed that to the client as an implementation they would ask for a framework to wrap it to hide the complexity and what is the point in that?

The same thing is accomplished just using JDBC as follows:

import java.sql.CallableStatement;
import java.sql.Connection;
import java.sql.Date;
import java.sql.DriverManager;
import java.sql.SQLException;

public class TestStoredProcedure {

    public static void main(String[] args){
        TestStoredProcedure t = new TestStoredProcedure ();
        t.test();
       System.out.println("Done!");
    }

    public void test() {
        Connection connection = getConnection();
        String myDate = null;
        try {
            myDate = test(connection);
        } catch (SQLException e) {
            //Might want to do something more useful here.
           e.printStackTrace();
        } finally {
            try {
                connection.close();
            } catch (SQLException e) {
                //don't care right now if we can't close it.
            }
        }
        System.out.println("Date:"+myDate);
    }

    public String test(Connection conn) throws SQLException {
        String result = null;
        CallableStatement proc = conn.prepareCall("BEGIN ? := sysdate(); End;");
        proc.registerOutParameter(1, java.sql.Types.DATE);
        proc.execute();
        result = proc.getDate(1).toString();
        proc.close();
        return result;
    }

    public Connection getConnection() {
        Connection conn = null;
        try{
            Class.forName("oracle.jdbc.OracleDriver");
            conn = DriverManager.getConnection("jdbc:oracle:thin:@localhost:1521:xe","scott","tiger");
        } catch (ClassNotFoundException e1) {
            e1.printStackTrace();
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return conn;
    }

}

So what was gained with the framework? To me it doesn’t seem like much. I’m not sure where the exceptions went to, do I get a Runtime exception if sysdate isn’t a function? I guess it means the user doesn’t have to access the CallableStatement or ResultSet directly and that *may* be a good thing to some people. IMHO saving yourself from learning JDBC just means that you won’t know what the problem may be when things start to go wrong and you just limited your skillset to a framework that not everyone is going to use.

Many frameworks are useful and I realize this part of the Spring framework is one small piece that probably isn’t used by very many people, but again, that’s kind of my point. Why bother with that piece at all?

Architects vs Developers: Theory vs. Practice?

I have always fallen on the practical side of technical architecture. I think it is because I started my professional life as a developer and have evolved into more of an architectural role on the projects I work on. I have worked with many architects over the years, though, I’m not sure where their background lies as most of them seem to fall more on the theoretical side of the fence.  It isn’t too often I run across a so-called architect who has the practical side of software down also.

These theory architects are good at writing documents and drawing pictures, and they even have some really great ideas. The downside of these theoretical architects have, is that though they tend to do a lot of research and generally know what all the best practices are, they don’t generally get down and dirty with the tool set and thus don’t know what the real or potential problems are with some of the practices that they suggest.  If there isn’t someone involved in the design who is fluent in the toolset, you could waste a lot of time trying to implement something that isn’t going to work or even just making a lot of small changes that aren’t going to matter in the overall scheme of things.

Regarding this point, I was involved in an interesting conversation with a technical architect on a client’s project recently. This architect is a great guy and in general I respect his opinions and suggestions much more than I generally do when dealing with architect types. However, this time, his tendency to constantly push theoretical best practices over practical approaches was apparent to me and even the client.

In creating an ADF BC layer in JDeveloper, a developer will typically, no always, use the wizard included in JDevleoper (unless, of course, they are using Evo). The way the BC layer is defined, various Entities xml files are created from tables in the database and views are built from those entities. Finally, in what is called an Application Module, the Views are used by defining instances of those views for use in the module. Since these view instances are generated automatically, each view instance has a number appended to it to make it unique. Makes sense, right?

Well, this architect said that it was a “best practice” rename those instance variables into something more meaningful. Now while I agree that it may be nice to rename some of those instance vairables to be something more meaningful, is it really practical, and thus is it really a “best practice” or is it just a good idea?

I interjected that though it may be a good idea, it hardly seemed practical, afterall, if JDeveloper automatically generates the instance names, don’t you lose some of the benefit of the automatic generation when you need to go back and rename all of those instances? At this point, the client joined in the converstation and asked if he had used this best practice in the past.

The architect replied that it is always a best practice to rename files or variables such as those so that the names have meaning. The client asked again, “yes, but do people actually do that in a project? Have you worked on a project in which that was done?”

The architect, much to my surprise, replied with, “well, to tell you the truth, I have never actually seen it done.” I actually had to laugh a little bit. It was actually refreshing to hear an architect say that though something was theoretically a best practice, in reality, it wasn’t done because it wasn’t practical. In a lot of organizations, practicality often loses out to so-called “best practices” many a time. The funny thing was, that in this project, it actually made sense to name our view instances as he suggested, but only because the tool we were using, Evo, would be automatically generating the instance names.

Maybe this article was just an excuse to print one of my favorite Yogi Berra quotes, “In theory, there is no difference between theory and practice. In practice, there is.”

What’s in a name?

A lot of people ask us where the name Vgo Software comes from. (That’s pronounced Vee-Go Software in case you were wondering.)  Since I’m in Greece this week with a client and I haven’t posted anything in a while, I thought I would expound upon where our name came from.

Vgo Software Inc.Back in the day, we were just a consulting company. At that time I had come up with a prototype for what eventually became our Rev product. I remember writing an e-mail to my business partner about this prototype. While writing the e-mail I realized that I did not have a name for the project and started to think about what I would call it.

Earlier that day I had talked to a consultant that was working for us and who was a friend of mine. He told me that he had been experiencing bouts of dizziness earlier in the week and didn’t know what was causing it. After suffering for a couple of days without it getting any better he went to the doctor to see what the problem was. As it turned out, the doctor told him he either had a cancerous tumor in his ear or he had Vertigo.

Thinking about what to name the software, which was a code generator, I thought “Vertigo!” what a perfect name! It generates code so fast it will give you Vertigo. Well, I put that in the e-mail as the name of the prototype and the name stuck for a while but at some point before we actually released it somebody did a name search and determined that the name Vertigo was actually being used by another software company for another product.

About a week later we held our monthly staff meeting where we gather everyone from wherever they may be, talk about current company events, and have beer and pizza. We decided it would be a good time to come up with a new name (esp. after the beer part). After everyone throwing out various names for about an hour, we finally settled on a mutilated version of Vertigo, Vgo.

Well, Vgo eventually became our code generator, Rev, and the product built on top of that which was once referred to as Vgo4Oracle became Evo (anybody notice a pattern emerging?). Both products were part of the “Vgo Software Suite” of products and we eventually just started using the name of the software itself as the name of the company.

How To Create An Editable List Page in ADF 11g

For those of you wondering how my presentation turned out in Atlanta this past Monday, I can tell you, it turned out very well technically, but as far as attendance was concerned it wasn’t exactly an arena-sized audience. I think the user’s group itself is more centered around DBA’s which is typical for these types of events.

This post covers one of the basic techniques I demoed in my presentation on Monday. A simple editable list page. I will do a series of posts starting with this basic concept and expanding upon it in subsequent posts adding functionality as we go.

An Editable List Page

A common type of functionality in a lot of Oracle Forms applications is to have a list of records in a block and allow the user to edit those records, delete those records, and even create new records.

In ADF 11g, this would translate to a JSP page that allows you to list the rows in a View, edit and delete from those rows and also create new rows. This functionality is actually very easy to create.

Let’s go over it step by step.

1. Create a new application in JDeveloper (File -> New -> Application(Fusion App)

JDeveloper will use a template to create the basic project and file structures needed for an ADF application.

2. Create the necessary Business Components from Tables.

Right-click on the Model project JDeveloper created in the previous step. In the New dialog, open the Business Tier node and choose ADF Business Components. In the right pane, choose Business Components from Tables.

You will now need to create a new database connection. Click the New button where it appears next to Database Connection. Set the name to something appropriate and set the attributes accordingly. You can use the Test Connection button to insure it gets created correctly.

Click OK and you should be back at the ADF Business Componens Wizard.

Click the Query button to the right of the wizard and JDeveloper will return a list of available tables and views that you can create Entities from. Select Departments and move it over to selected, then click on the Next button.

The next screen is the Updateable View Objects Screen, move the Entity over to the “Selected” column. Press “Next” and take all of the defaults until you can click “Finish”.

Click the “Save All” button.

3. Create the JSP Page

Right click on the ViewController project. Select “New”.

From the left pane, choose Web Tier -> JSF, from the right pane, choose “JSF Page’. Click “OK”.

Give the page a name like departmentList.jspx (We use the x at the end to denote an XML compliant JSP page, but it isn’t necessary).

Once the page has been created, open the Component Palette. Make sure the component list is “ADF Faces”. From the layout pane, choose the panelHeader and drag it onto the page. Click on the properties panel and change the text propery to “Department List”.

From the right side of the IDE, in the Data Controls pane, open the AppModuleDataControl. Click on the DepartmentsView1 object and drag it into the panelHeader. Choose Tables -> ADF Table from the create menu that pops up. At the confirmation dialog check Sorting, Filtering, and Row Selection to enable these features for the table. JDeveloper will create a table on the JSP page.

Next, drag a panelGroupLayout component from the Component Palette over to the panelHeader. Click on the properties list and change the layout from scroll to horizontal.

Next, open the DepartmentsView1 node in the AppModuleDataControl, open the Operations folder, drag the CreateInsert button into the panelGroupLayout. Click on properties and change the name of the button to “Add”.

Drag the delete button from the Operations folder over into the panelGroupLayout.

Open the Operatons folder of the AppModuleDataControl itself, it will have two operations, Commit and Rollback. Drag them over into the panelGroupLayout next to the other two buttons.

Congratulations! You’ve done it. Right click on the JSPX file and choose Run to see your masterpiece in action. You should be able to add rows into the table, edit existing row, and delete existing rows. None of it will be persisted to the database until you click “Commit” and you can always “Rollback” all your changes. You should also be able to filter the table with the input boxes on top and Sort it with the little triangles on the columns.

If you play with this example you may notice a couple little “bugs” or “features”. In my next post I will discuss a couple of these and how to mitigate them.

In the following weeks I will be expanding upon this simple demo to include ADF Task Flows and creating separate pages for creates and edits as well as a Master-Detail page or two.

How Not To Prepare For a Demo

Well, it’s one of those weeks for me.  I have about a half a gajillion things to do and one of them includes preparing for a presentation on Monday.  I have had the presentation prepared for a few weeks now and I’ve even presented parts of it over the last month, but I haven’t done any part of the live demonstration yet.  In fact, besides having a vague idea of what I want to show I haven’t really had any time to figure out exactly what the demo is going to be.  Real professional of me, isn’t it?

I had put together what I thought was a solution for a common problem in converting forms to ADF.  I had done most of it on a plane from Connecticut to Austin, TX a few weeks ago.  I didn’t have a ton of time to test it before my laptop’s battery ran out, but it looked like it worked so I was counting on showing that solution during my presentation.  Unfortunately, now, 3 weeks later, and mere days before the presentation I loaded it up again and tried it out and it doesn’t actually work like I had hoped.

So here I am trying to figure out what is wrong with it and get it working, hopefully before Friday so I can run through it on Friday with some of the folks in the office before doing it live on Monday.

It isn’t the usual way I like to prepare for these things.  When doing product demos I have a machine dedicated to the demos that only gets updated when I know it works, especially since it frequently is used to show of “new” features that are in development, I like to make sure I have a script that works and that the environment is always the same.  Too many other things can go wrong to leave any of it untested.

Well, at least if there’s something I’m good at, it’s being able to come through under pressure.  Besides there’s always the flight to Georgia…

A Friday Afternoon Music Post - Alkaline Trio

I’ve been lax with the music posts lately, too many presentations to prepare and technical stuff to get done, so I thought I’d take the time to post something today and liven up the blog a littel bit. All this talk about Forms, ADF, and Java can get a little dry sometimes.

Alkaline Trio has been around for a while now, and in my opinion they haven’t exactly been getting better. They are a 3 member (big surprise, there, paty poker netunbegrenztes frei spielgratis online poker gamespoker texas holdem pc gamepoker spielen spielgelddeutsches online pokerpoker bonus codestrip poker pc gameparty poker deposit bonusholdem poker turnieronline poker ohne geldparty poker bonuscodewww poker spielenpoker bonus reviewregeln für texas holdempoker bonus ohne einzahlungtexas holdem poker onlinegiochi on linestrip poker game online,strip poker online gratis,strip poker onlinegioco poker in italianogioco poker da scaricare7 card stud onlineonline gamesbet and win pokerstreap poker onlinesrtip poker gratisistruzioni gioco pokertorneo poker gratisstip poker onlinestrip poker online demotornei poker texas holdempoker slot gratisno deposit bonus pokergioco onlinepoker texas holdem onlinevideo poker gratisadvance cash loan payday,advance cash cash loan loan payday quick,advance cash loan payday todaycash advance,business cash advance,online cash advancecash till payday loaninstant online guaranteed cash advance credit card,cash advance from credit card,cash advance credit cardfree online casino gamblinghow to win at rouletteplay free slots gamemultistrike video pokerwinning at video pokercomputer black jackcasino secure online gamblingcraps free online play,free craps,free online casino game crapsfree black jack gameplaytech online casino heh?) punkish rock band with some definite goth tendencies which have been emphasized a lot more in later albums which have also become a little more mainstream.

My favorite Alkaline Trio album is “Maybe I’ll Catch Fire.” It has a lot of catchy tunes that are somewhat dark and comic in nature. The song “F* You, Aurora” about a town in Illinois named Aurora in which there was a bad car accident that took the life of one of the band members friend’s. It includes the lyric s “…And although it’s all my fault, The blaming myself had to come to an end. So I say:F*** you Aurora, you took my only friend. You won’t catch me behind the wheel, Of a Chrysler ever again.” Matt Skiba has a flair for good lyrics.

My other favorite song on the album is simple entitled “Radio”. It is one of the best I-hate-you and wish-you-would-die type of songs out there. With lyrics including “I wish you, would take your radio to bathe with you, plugged in and ready to fall,” and “while you’re taking your time with apologies, I’m making plans for revenge,” it gets my vote for one of the best sing-along songs ever. Not that I’m bitter or anything, but everyone has a bad day every once in a while and just needs to get it out somehow, don’t you think?

Other albums I would recommend by the Trio include “From Here to Infirmary” and “Goddammit”. “From Here to Infirmary” is definitely more pop-punkish than the other two, it has some better production values, and was their first album to get any real airplay. It is still pretty funny in that dark humor kind of way and so definitely worth a listen to.

That’s all I got for today, and the funny thing is, I’m in a good mood, not bitter at all, go figure.

Mapping Oracle Forms to ADF 11g - An Overview

 If you are looking to migrate your Oracle Forms applications to Oracle ADF applications, you have probably wondered about how they would map. You probably did a google search and ended up at the Oracle ADF Equivalents of Common Oracle Forms Triggers page. This isn’t a bad reference, but it only talks about triggers and there is a lot more to a form than just the triggers.

The basic outline of the mappings we use is shown in the diagram here. We essentially use Task Flows to encapsulate the entire functionality of what used to be a Form. The Task Flow allows all functionality including complex business logic, navigation, included popups and dialogs, and even other Task Flows to be shown visually in the Task Flow Designer page in JDeveloper.

Since transactions can be nested, when one form calls another, that can be shown in the Task Flow diagram also. Task Flows are also nice to use in that they can be used to encapsulate transactions.

Another mapping we typically use is to map what were Windows in Forms to JSPX pages in the ADF application. We typically use the JSPX extension to denote that the page is an XML-compliant JSP page. The Items within the Window or Canvases are mapped to ADF Controls.

Blocks map relatively well to Views if they are Query-based blocks. The attributes in the block become attributes on the view that is associated with the Entity that relates to the table the original Block was based on.

The link above that I included talks about transaction related triggers but what about other triggers, like WHEN-VALIDATE-ITEM? Where do those triggers get mapped? In our experience, those types of triggers require some more thinking to map and cannot just be mapped blindly. While it is true that you could map all of those types of triggers to a Java method if you wanted to, since ADF includes the Groovy expression language you probably wouldn’t really want to. Simple validations (and even some complex ones) can be performed in Groovy and thus would probably be best as Groovy expressions. If you could move the validation that was done at the UI level in the Form to the Entity level in ADF you would be even better off. That way you wouldn’t need to repeat the same expressions in every page that modifies that entity.

As June and ODTUG approaches I will be posting more and more excerpts from my presentation (of which this is one).  They will include more detail on some of the ADF features and how those features may apply to migrating Oracle Forms apps to ADF as well as some more step by step how-to guides that go into some of the development details on creating different types of screens in ADF.

Knowing When To ResultSet.Close() and When to Close Your Mouth

Just a quick story from a recent conference we spoke at. At a lot of these conferences or User’s Group meetings there is a question and answer period in which attendees ask questions of all the speakers. The questions I have heard have generally been technical in nature and since most of the speakers are pretty technical, there is a lot of expertise on the “panel”.

At a recent conference, an attendee asked a straightforward Java question. He wanted to know why after sometime of running his Java application, which was a web application running WebLogic, his application would start getting errors from the database that there were too many cursors open.

This is a pretty common problem for beginning Java developers using JDBC and I remember one time about 10 years ago (there I go dating myself again), when I was first working with JDBC I had a DBA come running over to me complaining that I was using up 50 connections to her precious development database. This was my first week at the job and she was an intimidating person. It was then that I learned all about closing connections, statements, and result sets when using JDBC.

Anyway, somebody there on the panel started immediately with “I don’t mean to be rude, but you can’t expect us to answer a question like that without knowing more details about your situation, like what is the application trying to acheive, why is it using JDBC, why are you retrieving a REF_CURSOR…?” and on and on a bit.

I finally managed to get a word in and told the guy, “You should make sure that you are closing your ResultSets and even your Statements in the finally clause of a try/catch block.” This apparently didn’t satisfy the first guy who continued to go on for another 20 minutes about how the every search is now a pagination and it doesn’t make sense to get an unlimited set of results if you are only showing 10 on the screen and how you should really use a PL/SQL Collection to and a stored procedure to return the exact set of results you want, and blah, blah, blah.

I again managed to interupt enough to put in my two cents that if you are forgetting to close ResultSets in JDBC you probably don’t want to bother trying to return PL/SQL Collections yet.

I explained this to my wife, who isn’t technical by comparing it to someone asking a question about cooking, whenever I cook chicken in a frying pan (non-teflon!) it sticks to the pan, what am I doing wrong? to which the simple reply would be “add some oil to the pan first”. The guy I am describing would answer with an entire explanation of why you should bake your chicken instead and insist you can’t get a good answer unless he knew all the spices you were using and the dish you were trying to cook.

I thought it was kind of funny and it was really no surprise that the first guy’s talk was on what? You guessed it…”PL/SQL Collections.”