Sunday Apr 29, 2012

Performance Test: DriverManager vs. DataSource

I was troubleshooting some well-traveled Java code the other day and hit an intriguing set of circumstances. The original developer(s) of this code -- a web application using JSP/servlets -- had written a data wrapper construct using DriverManager. After several upgrades of JDK and JVM, some minor cracks were starting to show.

We tried doing a direct transplant of DataSource-based code into the wrapper mechanism, effectively a one-for-one swap of the minimum number of lines of code without any real refactoring. Yes, I know...not a good idea for the long-term. But one has to start somewhere.  :-)

Interestingly, performance tanked. When things like that happen, it's time to get curious and dig deeper.

Why DataSource?

The DataSource approach to data connectivity brings numerous benefits with it (connection pooling, distributed transactions, etc.), but does it also carry a hefty performance penalty? I had never heard that it did. Either way, it's always good to do a little first-person testing to verify/refute findings. So off we go!

Testing Methodology

I put together a pretty simple test and ran it several times to factor out normal variations in environmental conditions. Using NetBeans, I created a plain-vanilla web application, sans frameworks. Next, I asked NetBeans to generate JPA entities from some tables in our database, and then an EJB (see this recent article for a refresher on connecting a basic EJB to underlying data via a DataSource) to provide the DataSource-based baseline. I then created an EJB that used DriverManager to build a connection and SQL statements for comparison.

Oh, and one last necessity: I created a couple methods to capture start/stop times using System.currentTimeMillis() for a timekeeper. That covered all the essentials.

And the Winner Is...

Well, there really wasn't a runaway winner strictly from a performance perspective. Results varied from run to run, but these two horses were neck and neck, often trading the lead by only a few milliseconds in consecutive runs...which is great news, considering that DataSource offers so much more and yet manages to retain the expected level of performance.

The bad news? Well, it's clear I have a lot of rework to do on this old code.

Sigh.  :-)

For more fun with Java, click here to follow Mark on Twitter.

Thursday Apr 19, 2012

Basic Bean Building: How to Quickly Create a JSF Managed "Look-up" Bean

If you're called upon to build a JSF application (large or small), NetBeans is a great tool to help you gain traction, and fast. I've mentioned previously how much I like the ability to do a quick first cut by creating your data structures and using NetBeans to generate a basic web app as a starting point. You go from nothing to working web application in short order, albeit a bit bare-bones. Still, what a great time-saver!

Let me toss out a few reminders and disclaimers. First, I'm a firm believer in rapid, iterative, and thoughtful development. No "paralysis of analysis" allowed, but OTOH, each step should be considered carefully as you go. Plan, execute, evaluate. Lather, rinse, repeat.  :-)

Second, build from small to large. Plan ahead, but make things work on a small scale and build out. This goes hand-in-hand with point #1, but it bears mentioning separately.

With those points in mind, I created a small sample project for use in this and future discussions: The Mighty Bean Coffee Company. Java is a wonderful thing in almost any form, so why not double our pleasure?

For the first iteration of our new project, I created an initial set of tables in a new MySQL database. These are the ones we'll be considering on our quest to create a JSF managed "look-up" bean:

Next, I created a new Java Web project, Web Application in NetBeans called MightyBeansWeb. Defaults were fine for our purposes here with the exception of selecting JavaServer Faces under Frameworks.

With the project created, I right-moused on MightyBeansWeb in the tree browser, chose "New Entity Classes from Database", and made the connections to the data source. Selecting the two tables modeled above, NetBeans provided us a couple of nicely-formed entity classes: Customer.java and CoffeeOrder.java.

Creating the JSF pages was also a snap. Right-moused again on the app, chose "New JSF Pages from Entity Classes", selected the classes and specified destination packages, and clicked finish. Et voila! We now have a working JSF web app. Go ahead, try it out. I'll be right here when you get back.  :-)

(Side note: Please feel free to a) update the toString() methods for more meaningful contents - this will come in very handy later! - and b) to refer to our recent article NetBeans, JSF, and MySQL Primary Keys using AUTO_INCREMENT to enable primary key auto-generation within MySQL.)

"That's great!" you say. But wouldn't it be nice to see which customer we've selected for our order? That brings us to the topic of this article. Let's whip up a look-up bean and make that happen now.

Right-mouse once more on the web app and choose "New JSF Managed Bean". Pick a name (I called this one "CustomerLookupBean") and a package and click finish. No need to do anything else on that panel since we're using Java EE 6.

Opening the class, we see it has annotations for @ManagedBean and @RequestScoped which serve our needs nicely. We just need to add a couple of very small things to wrap up our bean-work.

Since EJBs are non-reentrant, we can simply inject an instance of EntityManager into our lookup bean by adding the following lines to the class definition:
    @PersistenceContext(unitName = "MightyBeansWebPU")
    EntityManager em;
Clicking on the warnings in the left column prompts you to let NetBeans fix the imports. Yes, please!

Next and finally, we need to create a method to return the desired customer, something along the order of this:


This method issues a named Customer query using the ID provided and returns a single result. Since createNamedQuery returns a generic object, we cast it to what we know is coming back to us (a Customer object), then return the customer's full name. Not pretty, but good enough for a first cut.

Editing the appropriate list.xhtml file to display the customer's name instead of number is as simple as replacing <h:outputText value="#{item.customer}"/> with <h:outputText value="#{customerLookupBean.getName(item.customer.id)}"/> to query and receive the full customer name, taking us from this:

To this:

"Pretty" comes later, but this is a start. Any thoughts, comments, or questions? Please drop me an email or comment below!

All the best,
Mark

Wednesday Apr 11, 2012

How to Plug a Small Hole in NetBeans JSF (Join Table) Code Generation

I was asked recently to provide an assist with designing and building a small-but-vital application that had at its heart some basic CRUD (Create, Read, Update, & Delete) functionality, built upon an Oracle database, to be accessible from various locations. Working from the stated requirements, I fleshed out the basic application and database designs and, once validated, set out to complete the first iteration for review.

Using SQL Developer, I created the requisite tables, indices, and sequences for our first run. One of the tables was a many-to-many join table with three fields: one a primary key for that table, the other two being primary keys for the other tables, represented as foreign keys in the join table. Here is a simplified example of the trio of tables:


Once the database was in decent shape, I fired up NetBeans to let it have first shot at the code. NetBeans does a great job of generating a mountain of essential code, saving developers what must be millions of hours of effort each year by building a basic foundation with a few clicks and keystrokes. Lest you think it (or any tool) can do everything for you, however, occasionally something tosses a paper clip into the delicate machinery and makes you open things up to fix them. Join tables apparently qualify.  :-)

In the case above, the entity class generated for the join table (New Entity Classes from Database) included an embedded object consisting solely of the two foreign key fields as attributes, in addition to an object referencing each one of the "component" tables. The Create page generated (New JSF Pages from Entity Classes) worked well to a point, but when trying to save, we were greeted with an error: Transaction aborted. Hmm.

A quick debugger session later and I'd identified the issue: when trying to persist the new join-table object, the embedded "foreign-keys-only" object still had null values for its two (required value) attributes...even though the embedded table objects had populated key attributes. Here's the simple fix:

In the join-table controller class, find the public String create() method. It will look something like this:

    public String create() {
        try {
            getFacade().create(current);
            JsfUtil.addSuccessMessage(ResourceBundle.getBundle("/Bundle").getString("JoinEntityCreated"));
            return prepareCreate();
        } catch (Exception e) {
            JsfUtil.addErrorMessage(e, ResourceBundle.getBundle("/Bundle").getString("PersistenceErrorOccured"));
            return null;
        }
    }

To restore balance to the force, modify the create() method as follows (changes in red):

    public String create() {

        try {
            // Add the next two lines to resolve:
            current.getJoinEntityPK().setTbl1id(current.getTbl1().getId().toBigInteger());
            current.getJoinEntityPK().setTbl2id(current.getTbl2().getId().toBigInteger());
            getFacade().create(current);
            JsfUtil.addSuccessMessage(ResourceBundle.getBundle("/Bundle").getString("JoinEntityCreated"));
            return prepareCreate();
        } catch (Exception e) {
            JsfUtil.addErrorMessage(e, ResourceBundle.getBundle("/Bundle").getString("PersistenceErrorOccured"));
            return null;
        }
    }

I'll be refactoring this code shortly, but for now, it works. Iteration one is complete and being reviewed, and we've met the milestone. Here's to happy endings (and customers)!

All the best,
Mark

Sunday Mar 25, 2012

NetBeans, JSF, and MySQL Primary Keys using AUTO_INCREMENT

I recently had the opportunity to spin up a small web application using JSF and MySQL. Having developed JSF apps with Oracle Database back-ends before and possessing some small familiarity with MySQL (sans JSF), I thought this would be a cakewalk. Things did go pretty smoothly...but there was one little "gotcha" that took more time than the few seconds it really warranted.


The Problem

Every DBMS has its own way of automatically generating primary keys, and each has its pros and cons. For the Oracle Database, you use a sequence and point your Java classes to it using annotations that look something like this:


@GeneratedValue(strategy=GenerationType.SEQUENCE, generator="POC_ID_SEQ")

@SequenceGenerator(name="POC_ID_SEQ", sequenceName="POC_ID_SEQ", allocationSize=1)


Between creating the actual sequence in the database and making sure you have your annotations right (watch those typos!), it seems a bit cumbersome. But it typically "just works", without fuss.


Enter MySQL. Designating an integer-based field as PRIMARY KEY and using the keyword AUTO_INCREMENT makes the same task seem much simpler. And it is, mostly. But while NetBeans cranks out a superb "first cut" for a basic JSF CRUD app, there are a couple of small things you'll need to bring to the mix in order to be able to actually (C)reate records. The (RUD) performs fine out of the gate.


The Solution

Omitting all design considerations and activity (!), here is the basic sequence of events I followed to create, then resolve, the JSF/MySQL "Primary Key Perfect Storm":

  1. Fire up NetBeans.
  2. Create JSF project.
  3. Create Entity Classes from Database.
  4. Create JSF Pages from Entity Classes.
  5. Test run. Try to create record and hit error.

It's a simple fix, but one that was fun to find in its completeness. :-) Even though you've told it what to do for a primary key, a MySQL table requires a gentle nudge to actually generate that new key value. Two things are needed to make the magic happen.


First, you need to ensure the following annotation is in place in your Java entity classes:


@GeneratedValue(strategy = GenerationType.IDENTITY)


All well and good, but the real key is this: in your controller class(es), you'll have a create() function that looks something like this, minus the comment line and the setId() call in bold red type:


    public String create() {

        try {

            // Assign 0 to ID for MySQL to properly auto_increment the primary key.

            current.setId(0);

            getFacade().create(current);

            JsfUtil.addSuccessMessage(ResourceBundle.getBundle("/Bundle").getString("CategoryCreated"));

            return prepareCreate();

        } catch (Exception e) {

            JsfUtil.addErrorMessage(e, ResourceBundle.getBundle("/Bundle").getString("PersistenceErrorOccured"));

            return null;

        }

    }


Setting the current object's primary key attribute to zero (0) prior to saving it tells MySQL to get the next available value and assign it to that record's key field. Short and simpleā€¦but not inherently obvious if you've never used that particular combination of NetBeans/JSF/MySQL before. Hope this helps!


All the best,

Mark



Wednesday Mar 07, 2012

JPA Code Completion Coming to NetBeans IDE

Over at Geertjan's Blog (click here for article), he details one of the latest additions to the NetBeans daily builds: JPA code completion. I can't help but be excited about the timesaving features this brings to the table!

Being able to see your named queries in NetBeans 7.2 when calling EntityManager.createNamedQuery() is a really slick feature. Being able to CTRL-mouseover the named query (once selected) to see the underlying SQL is equally nice! Sanity checks while coding are ALWAYS welcome.  :-)

Some time back, I dipped my toe into the NetBeans world and found it nice but not overly compelling, choosing to use Eclipse for all Java development of any import. Now, I can't remember the last time I fired up Eclipse.

If you aren't already using NetBeans, visit the NetBeans website to download it and give it a try. It doesn't do everything for all people, but you'd be surprised at all it can do (and will in upcoming versions)...

All the best,
Mark
About

The Java Jungle addresses topics from mobile to enterprise Java, tech news to techniques, and anything even remotely related. The goal is to help us all do our work better with Java, however we use it.

Your Java Jungle guide is Mark Heckler, an Oracle Java/Middleware/Core Engineer with development experience in numerous environments. Mark's current work pursuits and passions all revolve around Java and leave little time to blog or tweet - but somehow, he finds time to do both anyway.

Mark lives with his very understanding wife, three kids, and dog in the St. Louis, MO area.



Stay Connected

Search

Archives
« April 2014
SunMonTueWedThuFriSat
  
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
   
       
Today