tags:

views:

57

answers:

6

I have inherited a bit of Java code that uses Hibernate. Some of the people using this code are now reporting that they are getting NullPointerExceptions all over the place.

I've been able to track this down and found that when we execute a query that pulls a list of objects from the database, that has a list of objects (that get pulled from a different table) Hibernate seems to be leaving holes in the list (NULL values). So the list may look something like:

Object
Object
NULL
Object

The code we are using to pull the information out of the database is:

List<PrinterGroup> groups = 
    this.getSession().createQuery( "from PrinterGroup" ).list();

And then inside each PrinterGroup is a list of Filters that have the NULL values in them.

While I could go around and find every instance were we loop over this list and add a NULL check I feel it is a bandaid fix, and there has to be a way to tell Hibernate to not pull null values in.

EDIT:

  • We are using Hibernate 3.2.2

EDIT2:

So the database seemed to be confusing. The PrinterGroup -> Filter relationship is a one to many relationship. So PrinterGroups have a list of filters. The problem is that list of filters has null values in it when it comes out of the database (There are no null values in the database by the way) and the list comes out looking like above.

EDIT3:

Here is the mapping relavant picese in the PrinterGroup HBM

<subclass name="PrinterGroup" discriminator-value="PG">
   <list name="filters"
              lazy="true"
              table="PG_FILTER"
               inverse="false"
                cascade="all-delete-orphan">

        <key>
           <column name="PG_ID" not-null="false"/>
        </key>
        <index column="LISTPOSITION"/>
        <one-to-many class="Filter"/>
     </list>

And the Filter is a pretty basic POJO mapping.

A: 

You should either null check, or you have to reorder the list to get rid of the null. Its a pain.

hvgotcodes
+1  A: 

Ok, so the PrinterGroup objects are not themselves null, but they have null references to objects of type Filter? Or non-null references to Lists of Filters, which contain null Filters?

The obvious answer is that the database contains a many-to-many relation between PrinterGroup and Filter, and has database null values for filters, e.g.:

 select * from printer_group_filter;
 id    printergroup_id   filter_id
 1     1                1
 2     1                null
 3     1                2
 4     2                1
 5     2                null

If it's possible for a filter to be null, well, that's your requirement. Or you can use the NullObject idiom to make "the null filter" an actual object, though this isn't going to be straightforward with Hibernate.

If it's not possible for a filter to be null, fix your data, add a not-null constraint to the many-to-many, and fix your input validation to prevent the addition of more nulls.

tpdi
I've editing my post. There is a one to many relationship between the PrinterGroup and Filter tables. So PrintersGroups might have many filters. When we get the list of them in Java there are null values in the list of Filters.
Patrick
A: 
List<PrinterGroup> groups = this.getSession().createCriteria( PrinterGroup.class ).add(Restrictions.isNotNull("filters")).list();
Daniel Moura
A: 

If I could leave this in a comment I would (low rep): Can you post the mapping for PrinterGroup?

tQuarella
A: 

How about just filtering out null filters using HQL

List<PrinterGroup> groups = 
    this.getSession().createQuery( "Select pg from PrinterGroup pg where pg.filter is not null" ).list();

I assume your property is called 'filter'

Greg
+2  A: 

Is this collection mapped with a <list> (or other indexed collection) and <list-index>?

All collection mappings, except those with set and bag semantics, need an index column in the collection table. An index column is a column that maps to an array index, or List index, or Map key. ... The index of an array or list is always of type integer and is mapped using the element. The mapped column contains sequential integers that are numbered from zero by default.

I would imagine that when using an indexed collection, if your index column has gaps in it (i.e. it has values like 0, 1, 3, 7) that Hibernate would populate the resulting List with empty elements at the expected places.

matt b
This is correct. If you have gaps in your numbering sequence you'll get nulls in the returned list.
Cowan
This is exactly what is happening. Now to figure out how to correct this on an already active system.
Patrick
change the database values so that LISTPOSITION values are contiguous?
matt b