Limiting Results in SQL Queries When Using Oracle

Posted on May 22, 2006 by Scott Leberknight

A long time ago, in a galaxy far away I posted about limiting the number of query results when performing SQL queries having ORDER BY clauses in them. For example, you might want to run a SQL query that sorts people by last then first name, and returns rows 41-50. You then might want to go to the next "page" of results, still sorting by last then first name, which is rows 51-60. That post talked about how easy it is to do using MySql, and it is because MySql provides the lovely "LIMIT" clause. Oracle, on the other hand, seemingly makes it very difficult to do what is quite simple conceptually. I am pretty sure that's on purpose, so you have to spend $300 per hour for one of their service consultants. Alternatively, you could use something like Hibernate to figure out how to write queries like this in Oracle, without spending a dime.

So basically I give all the credit to Hibernate and its developers as they obviously figured this out and incorporated it nicely into their product, abstracting away all the pain. So in Hibernate you could write the following Java code:

Criteria criteria = session.createCriteria(Person.class);
criteria.addOrder(Order.asc("lastName"));
criteria.addOrder(Order.asc("firstName"));
criteria.setFirstResult(40);  // rows are zero-based
criteria.setMaxResults(10);
List results = criteria.list();

So now all we have to do is turn the hibernate.show_sql property to true and look at the SQL that Hibernate generates. So I ran the query and figured out the gist of what Hibernate is doing. Here is an example of a SQL query you could run in Oracle, formatted for readability. That is, assuming you consider this query readable at all!

select * from
    ( select row_.*, rownum rownum_ from
        (
            select * from people p
            where lower(p.last_name) like 's%'
            order by p.last_name, p.first_name
        )
      row_ where rownum <= 50
    )
where rownum_ > 40

Isn't that intuitive? How nice of Oracle to provide such a succinct, easily understandable way of limiting a query to a specific set of rows when using ORDER BY. Also, note that the entire reason we have to go through all these hoops is because Oracle applies the special rownum pseudo-field before the ORDER BY clause, which means once the results have been ordered according to your criteria (e.g. last name then first name) the rownum is in some random order and thus cannot be used anymore to select rows N through M.

So what is exactly going on in the above query? First, the actual query is the innermost query which returns all the possible results, ordered the way you want them. At this point the results are in the correct order, but the rownum for this query is in some random order which we cannot use for filtering. The query immediately wrapping the actual query selects all its results, aliases rownum as rownum_, and filters out all rows where rownum is equal to or less than 50. Note that the values of rownum_ will be in the correct order, since the rownum pseudo-column has been applied to the results of the already sorted innermost query.

So if we stopped now we'd have rows one through 50 of the actual query. But we only want rows 41-50, so we need to wrap our current results in one more outer query. This outermost query uses the aliased rownum_ column and only includes rows where rownum_ is greater than 40. So that's it. A generic solution you can use for paging result sets in Oracle databases. One caveat: I've not done any performance testing on this and so don't really know whether first selecting all results before filtering them in the database would cause performance problems on really large numbers of results. It certainly seems that it could affect performance, but then again how else could you sort the results and grab some set of rows in the "middle" of the results without using a technique similar to this? I suppose if I were really enterprising I could look under the covers of some other database whose code is open source, and which has a simple syntax for limiting the rows, to find out how databases internally handle and perhaps optimize this kind of thing, but it is late and I'm already going to be hating myself for staying up this late as it is.

Display Error Messages For Multiple Models in Rails

Posted on May 22, 2006 by Scott Leberknight

Normally in Rails when you want to display validation error messages for a model object, you simply use the error_messages_for() helper method. For simple sites this is usually just fine, as it displays a message stating that something went wrong along with a list of validation error messages. If you use the Rails helper methods to generate your HTML controls, then those fields are also wrapped in a div element which can be styled to indicate there were problems with that field. So you have some explanation of the validation errors, generally at the top of the page, and the fields where validation errors occurred can be styled as such, for example with a red outline or a red backgroun or whatever makes it clear to users there is a problem with the field.

This works very well when you are validating a single model object. But what if you are validating multiple models? You could have a separate error_messages_for() for each model object. That will work, but it is ugly, since you'll have a separate list of error messages for every model object you are validating. I searched the Rails API and could not find a method to display errors for multiple models, so I wrote one that is based on the error_messages_for() method. Basically I copied Rails' error_messages_for() method and then modified it to display messages for multiple models.

It works like this. You pass in an array of object names for which to collect and display errors instead of a single object name. The first object name is assumed to be the "main" object (e.g. the "master" in a master/detail relationship) and is used in the error explanation should any validation errors occur. For example, assume you have a page that allows you to create a stock watch list and also add stock ticker symbols for that watch list. The "main" object here should be the watch list object, and if validation errors occur then the message the gets printed is "2 errors prohibited this watch list from being saved." This makes some sense, at least to me, since the watch list is the main thing you are saving; the stock ticker symbols can be entered if the user wants, but are not required since they could be added later. As with the Rails error_messages_for() method, you can pass in additional options.

That's pretty much it, except for the code. So here is the code:

def error_messages_for_multiple_objects(object_names, options = {})
  options = options.symbolize_keys
  object_name_for_error = object_names[0]
  all_errors = ""
  all_errors_count = 0
  object_names.each do |object_name|
    object = instance_variable_get("@#{object_name}")
    if object && !object.errors.empty?
      object_errors = object.errors.full_messages.collect {
        |msg| content_tag("li", msg)
      }
      all_errors_count += object_errors.size
      all_errors << "#{object_errors}"
    end
  end

  if all_errors_count > 0
    tag = content_tag("div",
      content_tag(
        options[:header_tag] || "h2",
        "#{pluralize(all_errors_count, "error")} prohibited this" \
        " #{object_name_for_error.to_s.gsub("_", " ")} from being saved"
      ) +
      content_tag("p", "There were problems with the following fields:") +
      content_tag("ul", all_errors),
        "id" => options[:id] || "errorExplanation",
        "class" => options[:class] || "errorExplanation"
    )
  else
    ""
  end
end

The code works like this. First we extract the name of the "main" object as the first element of the object_names array. Next we loop through all the model objects, checking if there are any errors. If there are errors we collect them in a string containing an li tag for each error and append them to the all_errors string. Once we've checked all the objects for errors, and if there were errors, we wrap all_errors in a div containing a header, the main error message, and finally create an unordered list and stuff all_errors in that list. If there were no errors at all we simply return an empty string. That's it. Now you can easily display a list of validation errors for multiple model objects, using code like this: error_messages_for_multiple_objects( ["watch_list", "stock1", "stock2"] ). Of course if we have an unknown number of stocks in this case, then we could construct the array of object names first and then pass it into the method, which would be more flexible.

JavaOne Summary

Posted on May 22, 2006 by Scott Leberknight

I am sitting in Oakland Airport waiting for my plane back home, so I thought I'd actually write a quick summary about JavaOne which I just attended this past week. I went to the 2003 and 2004 editions of JavaOne, and after that had decided not to come back as the quality of technical content was very low, especially compared to boutique conferences like No Fluff Just Stuff where almost every speaker is a book author, a well-known industry expert, an author of some popular open-source framework, or just is an excellent speaker and expert in their topic. But one of my friends went in 2005 (he was lucky enough to get a free ticket) and said that Sun had done a lot to improve the technical content and speaker quality; mostly it seemed they started inviting No Fluff speakers and other industry experts. So this year, after looking at the session descriptions and seeing a bunch of No Fluff speakers, people like Rod Johnson, Josh Bloch, and Neal Gafter, I decided to give it a try again. There's certainly no question JavaOne is always a good time with good parties, lots of food, lots of drinking, and is really a vacation!

Overall the conference was pretty good, and the speakers were in general very good. Then again, I did attend mostly sessions given by speakers I already knew were good and avoided the vendor-driven talks on EJB 3, JSF, and other such things that I never plan to actually use in a real project. I only attended the conference opening General Session on Tuesday morning, and found it to be quite anemic. Even the announcement that Sun planned to open source Java was subdued and not really much of an announcement - in fact most people sort of looked around and seemed to be asking "Did they just say they were going to open source Java?" since the way they announced it was so, well, lame. Much of the conference centered around the "Compatibility Matters" theme and the ubiquitous "Ease of Use" mantra, also known as "Ode to Visual Basic Programmers."

It continues to amaze me that the people doing the EJB 3 specification don't really seem to have learned much from Spring and Hibernate. Oh, they say they have a POJO-based programming model, inversion of control, dependency injection, and AOP, but in reality they are very limited and basic and don't approach the power that Spring provides, for example. There are annotations all over the place, which do remove a lot of the need for mounds of XML configuration code, but the "POJOs" are now littered with EJB imports, since you need to import the annotations you plan to use. So if you import the EJB annotations, are the POJOs really POJOs? Adding the @Stateless annotation to get yourself a stateless session bean still ties you to an EJB container. In Spring you are not tied to anything, and you generally don't have framework or vendor-specific imports in your classes, and most definitely not in your interfaces. And because the new JPA (Java Persistence API) does not include a "Criteria" API nor any notion of a second-level cache a la Hibernate, why in the world would I choose it over Hibernate 3?

I did attend some pretty interesting "non-standard" talks on things like JRuby, grid computing, TestNG, and Spring. I say "non-standard" because they are not the typical vendor-driven talks and are about topics that are not "standard" Java EE. It is refreshing that Sun has finally allowed these types of talks and has realized that not all Java developers are using the "standard" Java EE technologies as found in the specifications. Other interesting talks included one about new JVM features designed to permit dynamically typed languages like Ruby and Python to run on the JVM; and the new scripting language features built into Java SE 6. Initially I thought the addition of scripting support directly in the Java SE was a little silly, but after going to several talks I now at least see some potential benefits to it and think it might actually be a Good Thing - only time will tell I suppose.

Overall I think I got my money's worth, and that even included an appearance at the "After Dark Bash" from the Mythbusters who shot some t-shirts at extremely high velocities across the Moscone Center! Assuming Sun keeps bringing back the good speakers and keeps permitting the "non-standard" topics, I just might keep going back!

Declaring Transaction Attributes on Spring's TransactionProxyFactoryBean

Posted on January 23, 2006 by Scott Leberknight

One of the (many) benefits of using Spring for web application development is that you can declaratively define transaction boundaries on POJOs, e.g. business service layer classes that delegate to one or more DAOs underneath. One of the simplest ways to do this is to use Spring's TransactionProxyFactoryBean to specify how to apply transactions to methods on a proxied object. Without going into all the gory details of how Spring AOP works, using dynamic proxies and such, there is something to watch out for when using this useful class. Typically when using TransactionProxyFactoryBean you'll create a parent bean definition in your Spring ApplicationContext which defines the transaction manager and the transaction attributes. You then create child beans which inherit the transaction manager and transaction attributes. For example:

<bean id="abstractTransactionProxy"
    abstract="true"
    class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
    <property name="transactionManager" ref="hibernateTransactionManager"/>
    <property name="transactionAttributes">
        <props>
            <prop key="get*">PROPAGATION_SUPPORTS,readOnly</prop>
            <prop key="find*">PROPAGATION_SUPPORTS,readOnly</prop>
            <prop key="is*">PROPAGATION_SUPPORTS,readOnly</prop>
            <prop key="*">PROPAGATION_REQUIRED</prop>
        </props>
    </property>
</bean>

You would then create child beans which inherit from abstractTransactionProxy and which are your actual service POJOs. For example:

<bean id="customerService" parent="abstractTransactionProxy">
    <property name="target" ref="customerTarget"/>
</bean>

<bean id="productService" parent="abstractTransactionProxy">
    <property name="target" ref="productTarget"/>
</bean>

Easy enough, right? The child beans will now inherit the transaction manager and all the transaction attributes. The definition of transaction attributes in abstractTransactionProxy specifies several things. First, any method whose name begins with "get", "find", or "is" will support execution within a transaction, and the "readOnly" marker indicates that they can be executed in a read-only mode. So, if one of these methods is called when there is no existing transaction, then no transaction will be created and the method executes without the overhead of a database transaction. If one of the methods is called when there is an existing transaction, it simply inherits the transactional context and executes within the transaction. So far so good. Now, the last part of the transaction attributes definition specifies a "*" as the method name, meaning any other method whose name doesn't start with "get", "find", or "is." In addition, any other method is required to execute within a transaction. If an existing transaction exists the method will inherit the transactional context; if not then a new transaction will be automatically created. The "*" acts as a catch-all against a developer who adds a new method that must execute transactionally but who forgets to add the method to the transaction attributes definition. Take the following example:

<bean id="abstractTransactionProxy"
    abstract="true"
    class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
    <property name="transactionManager" ref="hibernateTransactionManager"/>
    <property name="transactionAttributes">
        <props>
            <prop key="create*">PROPAGATION_REQUIRED</prop>
            <prop key="update*">PROPAGATION_REQUIRED</prop>
            <prop key="delete*">PROPAGATION_REQUIRED</prop>
            <prop key="*">PROPAGATION_SUPPORTS,readOnly</prop>
        </props>
    </property>
</bean>

What's the difference here? In this case, if a developer doesn't follow the naming conventions for "bang" methods - methods that insert, update, or delete database records - then no transactions are applied and their changes will not be committed to the database. For example, suppose a developer creates a method named "saveProduct" in a class which has the above transaction attributes applied to it. What happens? It supports an existing transaction but if called without an existing transaction it will execute non-transactionally and in a read-only fashion, since the "*" transaction attribute is the rule that applies. Thus the database changes would never take effect! In fact, if the method is sometimes called when there is an existing transaction and sometimes not, a subtle bug would arise since sometimes the database changes would be committed and sometimes not! To allow developers to add methods whose name begins with "save," you would have to add another transaction attribute definition. Even worse, what happens if no rule matches a given method? Take the following:

<bean id="abstractTransactionProxy"
    abstract="true"
    class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
    <property name="transactionManager" ref="hibernateTransactionManager"/>
    <property name="transactionAttributes">
        <props>
            <prop key="create*">PROPAGATION_REQUIRED</prop>
            <prop key="update*">PROPAGATION_REQUIRED</prop>
            <prop key="delete*">PROPAGATION_REQUIRED</prop>
        </props>
    </property>
</bean>

For this example, if a method named "saveProduct" is executed, none of the above transaction attributes apply, and the method is assumed to be non-transactional. So what is the point of all this? There are several. First, define your transaction attributes explicitly for read-only methods like "get*" and "find*". Second, have the read-only method definitions support an existing transaction using PROPAGATION_SUPPORTS and add the readOnly marker. This ensures that when there is no existing transaction, the method executes non-transactionally and may be optimized by the JDBC driver and database to be read-only. Third, add a "*" rule to the transaction attributes definition which specifies the default transaction rule. Fourth, make this default catch-all rule be as conservative as possible. Usually you will want to use PROPAGATION_REQUIRED, as this will require the method to execute within an existing transaction or create a new one. It is much better to have a read-only method execute transactionally than have a bang method which changes database state execute non-transactionally, even though it will have additional overhead. Finally, perform code reviews or write a script or find some way to automate checking that your naming conventions are being followed so that methods execute with the correct transactional context.

No One "Caught" It?

Posted on January 14, 2006 by Scott Leberknight

Apparently none of the <sarcasm>tons of people who read my blog</sarcasm> caught the fact that in my test failings part ii entry the test code is wrong. (I only caught it because I read that entry as I was writing abour validation in Rails.) If the line of code dao.findVisit(-9999L) executes without throwing any exception, then the test still passes! Just because the test method throws Exception and the try/catch only deals with HibernateObjectRetrievalFailureException does not mean the test fails when the findVisit method throws no exception at all. You still need to remember to call fail() if no exception is thrown, as the following shows.

public void testFindNonExistentVisit() throws Exception {
    try {
        dao.findVisit(-9999L);
        fail("findVisit should have thrown an exception!");  // you do need this line!
    }
    catch (HibernateObjectRetrievalFailureException ex) {}
}

So even though all the ExceptionAssertionTemplate code is more verbose (hey, it's what you expect from Java developers, right?) it still ensures that you don't forget to add the call to fail() in your test methods. I don't think it's that much more verbose, and since I apparently cannot even get my code correct in a blog entry, it's probably a good idea to use it, or else I'll keep forgetting to call fail() and have my tests passing when they should fail.

Supressing Validation in Rails On Fields That Are Not Required

Posted on January 14, 2006 by Scott Leberknight

I've been really busy since my last post, which was was back in October of last year. Time goes by too damn fast! Anyway, I've been mucking around with Ruby on Rails lately and was adding some validation to a model object. I had a bunch of fields that are not required, but if a value is entered they should be validated against a specific format. In my case email addresses and phone numbers. Normally to validate the format of a field in Rails you can simply write the following. (Note that EMAIL_FORMAT is a Regexp object created as a constant in the class in case you wonder where it came from.)

validates_format_of :email,
                    :with => EMAIL_FORMAT,
                    :message => 'must be a valid email address, e.g. a@b.com'

That is all well and good except for the minor problem that this will cause Rails to run validation on the email field regardless of whether it is empty or not. So even though the field isn't required, Rails will validate it and report an error back to the user. Not exactly what I had in mind.

So after some extensive Googling, I found some documentation and examples that use the :if option along with a Proc object, which I have heard of but don't really understand. I'll learn that later, as for now I simply want to make the validation work properly. So the following code will validate the email address, but only if the user actually entered a value.

validates_format_of :email,
                    :allow_nil => true,
                    :with => EMAIL_FORMAT,
                    :if => Proc.new {|c| not c.email.blank?},
                    :message => 'must be a valid email address, e.g. a@b.com'

So that's how you do it. You create a new Proc object with a block that checks whether the field you are validating is blank. Rails will only run validation on the email field if it's not blank. Note that I also used the allow_nil option to tell Rails that a nil value is OK. If the value is nil then validation is suppressed. But won't that take care of blank values sent in from a web form? Unfortunately Rails (at least by default) will not convert empty strings received from the HTTP request parameters to nil automatically. If it did, then the :if option would not be required in the validation. So if, for example, you sent a GET request with the query string "first_name=Scott&last_name=Leberknight&email=&cell_phone=&home_phone=", Rails would assign empty strings to email, cell_phone, and home_phone request parameters. Or perhaps I should say it simply takes the request parameters as they are sent by the browser and assigns the values sent by the browser. This behavior is the same for POST requests when you don't fill out a value for things like text fields and text areas, select lists, etc. in forms. The crappy thing about empty strings is that they'll be stored in your database as empty strings rather than as null values. That's something to research later, as I want null values instead of empty strings in my database.

Test failings, Part II

Posted on October 27, 2005 by Scott Leberknight

A co-worker, when I showed him the ExceptionAssertionTemplate and ExceptionAssertionCallback, took one look and said, "Why don't you just catch the exception you are expecting, have your test throw Exception, and be done with it?" For example,

public void testFindNonExistentVisit() throws Exception {
    try {
        dao.findVisit(-9999L);
    }
    catch (HibernateObjectRetrievalFailureException ex) {}
}

Um, yeah, why wasn't I just doing that? It is simpler and less code. Thanks Andrew!

Ensuring Your Tests fail() When They Should

Posted on October 24, 2005 by Scott Leberknight

A few weeks ago I posted about how I use the fail() method immediately after an Exception should have been thrown, in order to ensure that invalid input or use of the method results in the exception that is expected. Since manually remembering to call fail() in every one of these situations is simply not going to work (at least not for me), I wrote a couple of quick and dirty utility classes to help out. They are based on a Spring-like Template/Callback approach, and embed the code I don't want to forget in the template class so that it is impossible to forget to call fail().

The template class is currently called ExceptionAssertionTemplate and contains two overloaded execute() methods. Here it is, with all my verbose JavaDocs and such.

package com.sleberknight.tests;

import junit.framework.Assert;

/**
 * Template class for use by unit tests that want to perform actions
 * that cause expected exceptions and then  assert the exception
 * was thrown and is of the correct type.
 *
 * @author Scott Leberknight
 */
public class ExceptionAssertionTemplate {

    /**
     * Executes the specified ExceptionAssertionCallback and
     * fails the test if no exception was actually thrown. Does not check
     * the type of exception that was thrown. Any thrown exception is
     * considered a successful test.
     *
     * @param callback
     */
    public void execute(ExceptionAssertionCallback callback) {
        try {
            callback.doActionCausingException();
            Assert.fail("Should have thrown an exception ");
        } catch (Exception e) {
        }
    }

    /**
     * Executes the specified ExceptionAssertionCallback
     * and either fails the test if no exception was actually thrown or
     * asserts that the exception thrown is of the expected type.
     *
     * @param callback
     * @param expectedExceptionType
     */
    public void execute(ExceptionAssertionCallback callback, Class expectedExceptionType) {
        try {
            callback.doActionCausingException();
            Assert.fail("Should have thrown a " + expectedExceptionType.getName());
        } catch (Exception e) {
            Assert.assertEquals(expectedExceptionType, e.getClass());
        }
    }

}

So to use it you need a ExceptionAssertionCallback, which is where you put code that should throw an exception. The no-arg execute() method executes the callback and fails the test if no exception was thrown. The execute() method that takes the expectedExceptionType argument additionally asserts that the thrown exception is of the expected type. So here is the callback class implementation.

package com.sleberknight.tests;

/**
 * Callback class that unit tests can use to perform actions that should throw exceptions.
 *
 * @author Scott Leberknight
 */
public abstract class ExceptionAssertionCallback {

    /**
     * Implement this method to throw the expected exception.
     *
     * @throws Exception
     */
    public abstract void doActionCausingException() throws Exception;

}

That's it. The ExceptionAssertionCallback is an abstract class with one method, doActionCausingException(), which must be implemented. So how do you use these classes? Here is a simple example, in which I have a DAO I am testing a findVisit() method with a non-existent record in the database. This method should throw a HibernateObjectRetrievalFailureException when called with an invalid identifier. So basically you create the template, and then call the execute() method, passing in the callback, defined here as an anonymous inner class. Note that dao is defined as a private instance variable in the test case, and is thus available to use in the callback. The template then executes the callback's doActionCausingException() method and verifies that it throws an exception of type HibernateObjectRetrievalFailureException. Assuming it does, the test passes. Otherwise, the test fails.

public void testFindNonExistentVisit() {
    ExceptionAssertionTemplate template = new ExceptionAssertionTemplate();
    template.execute(new ExceptionAssertionCallback() {
        public void doActionCausingException() throws Exception {
            dao.findVisit(-9999L);
        }
    }, HibernateObjectRetrievalFailureException.class);
}

You could of course create a base test case that creates the ExceptionAssertionTemplate, which I actually did, and then there is even less code in your test as you can then just use the existing template that was created for you. But the main point here is that by using this approach, you cannot forget to fail() the test ever again.

Using Spring with Hibernate3's Lazy-Load Everything Approach

Posted on October 22, 2005 by Scott Leberknight

I am writing this so that I never, ever, ever forget how the new default lazy-load behavior in Hibernate3 can completely mess with your head for hours and hours of debugging when you are expecting Spring's HibernateTemplate's load method to throw a HibernateObjectRetrievalFailureException in a unit test, only to find the reason is quite simple but subtle! Oh, and of course if anyone else is reading, or more importantly, Googling, then hopefully this will help you too.

I have an implementation of a DAO that extends Spring's HibernateDaoSupport class which has a finder method for an entity given the unique identifier, which is of type Long. That finder method basically does this:

public Entity findEntity(Long id) {
    return (Entity)getHibernateTemplate().load(Entity.class, id);
}

Note specifically that I am using the load() method which is defined to "Return the persistent instance of the given entity class with the given identifier, throwing an exception if not found." Specifically, this method should catch any HibernateException subclass thrown by the internal HibernateCallback and convert it into the appropriate class in the Spring DataAccessException hierarchy, e.g. in this case it should be converted to a HibernateObjectRetrievalFailureException if I pass in an identifier for which there is no persistent entity. So far, so good.

Next I have a simple unit test that calls my finder method using an invalid identifier, and then it asserts that the appropriate exception was thrown. Basically it looks something like this:

public void testFindEntityUsingInvalidIdentifier() {
    final Class expectedExceptionType = HibernateObjectRetrievalFailureException.class;
    try {
        dao.findEntity(-9999L);
        fail("Should have thrown an " + expectedExceptionType.getName());
    } catch (Exception e) {
        assertEquals(expectedExceptionType, e.getClass());
    }
}

So I ran this test thinking it was a no-brainer. It failed. In fact, it failed with the message "junit.framework.AssertionFailedError: Should have thrown a org.springframework.orm.hibernate3.HibernateObjectRetrievalFailureException." Um, what? I was about 100% sure there was no such row in the database, since I was using Spring's AbstractTransactionalDataSourceSpringContextTests test class which ensures transactions are rolled back after each test, and because I knew I didn't put any data in the database with that identifier. So that meant the findEntity method did not throw any exception. I started adding the old fallback System.out.println() statements all over the place to see what exactly was going on. The finder method actually was returning a non-null object, but when I tried to call any method on it, like toString(), it then threw a raw Hibernate ObjectNotFoundException, which as of Hibernate3 is unchecked not checked. Hmmm. Performed some initial debugging using a real debugger no less and found that proxy objects were being returned, and then looked in the stack traces and saw some CGLIB stuff in there, meaning the entity object was in fact proxied.

Since the object was actually a proxy, that explained why no exception was thrown by HibernateTemplate.load() - since no methods had been called on the proxy yet, Hibernate3 was happily returning a proxy object for an identifier which does not really exist. The second you call any method on that proxy, you get the Hibernate ObjectNotFoundException. Did a bunch of research and finally found that the Hibernate3 reference guide, in Section 11.3 (Loading an object) mentions that "load() will throw an unrecoverable exception if there is no matching database row. If the class is mapped with a proxy, load() just returns an uninitialized proxy and does not actually hit the database until you invoke a method of the proxy." I then did more research and arrived at a resource I should probably have looked at much sooner, as this is my first time using Hibernate3 (I've been using Hibernate2.x for a while now). That resource is the Hibernate3 migration guide which mentions that Hibernate3 now defaults to lazy="true" for everything, both classes and collections. I even remember reading this a while back but it didn't occur to me that the load() method in the Hibernate Session would behave like that.

In any case, with lazy loading set to "true" because of the changed default value in Hibernate3, the Spring HibernateTemplate.load() basically is useless for lazily initialized objects, since it will not catch any Hibernate exceptions and thus won't ever do the conversion into one of the DataAccessException subclasses. There are a few solutions or workarounds or hacks or whatever you want to call them. First, you could set default-lazy="false" in your root hibernate-mapping element, which will switch the behavior back to what it was in Hibernate2.x. That is what I did to verify that my test would work properly when there was no proxying involved. Second, you can use the HibernateTemplate.get() method instead of load() (which delegates to the Hibernate Session.get() method) because get() "hits the database immediately and returns null if there is no matching row" and then if the result is null, throw the appropriate exception yourself. Third, you can leave Hibernate3's default behavior alone and override it for specific classes and/or collections. For collections I almost always use lazy loading but I had never done it for classes. So you could set lazy="true" for specific mapped classes in your Hibernate mappings.

I fully understand why you want to lazily initialize your collections, but I am not sure why I would want the default behavior for normal classes to be lazy load. When I perform a find for a specific object, I pretty much know I want that object since I am going to do something with it, like display it in a web page or something. I suppose one use case for lazy initializing classes would be if you perform a query and get back a list of objects, and you don't want to initialize all of them until the user actually needs them. But even in that case I generally am going to display the search results and I will be using those objects. So I am still somewhat at odds for when I would realistically want this behavior; even for search results I can retrieve only the results I need by using Hibernate's ability to set the start row and number of rows returned for a query.

So, the main point of all this is that the default lazy loading of everything in Hibernate3 may cause some unexpected problems, and if you start seeing CGLIB in stack traces and weird things are happening, chances are you've got an object proxy rather than the actual objct you thought you were getting, and that the proxy is causing some weird behavior. Whew!

Don't Forget To fail() Your Tests

Posted on October 05, 2005 by Scott Leberknight

Often when writing JUnit tests, I use the fail() method immediately after an Exception should have been thrown, in order to ensure that invalid input or use of the method results in the exception you expect. However, earlier this week I was updating a test case and noticed one test method that was expecting an exception to occur did not have a call to fail(). So this is the code that should have been in the test:

public void testSomethingFailsThatYouExpectToFail() {
    try {
        SomeObject someObject = new SomeObject();
        someObject.someMethodThatShouldFail("invalid input");
        fail("Should have thrown IllegalArgumentException");  // need this line!
    }
    catch (Exception ex) {
        assertEquals(IllegalArgumentException.class, ex.getClass());
    }
}

But the code in the test did not have the fail() method call. Without fail(), this test works as expected only when the method actually throws the exception and the assertion validates the type of exception thrown. If, on the other hand, the exception is not thrown then the test passes but is not actually a valid test!

So as a result I did a quick search through all tests and found a significant number where I or one of the other developers had forgotten to call fail() immediately following the method call where we expect an exception to be thrown, which I then had to fix by adding the call to fail() back in. After doing that I found there were actually three tests that then failed. So even though these were exceptional test cases I had to fix the offending code. Maybe I can write a Checkstyle or PMD rule that would detect this type of error in unit tests, because it is so easy to forget to call fail(), have the test pass, and move on to the next task.