Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
HomeAnnouncementsWhite Papers
Discussion GroupsFirst AidDatabasesJavaBeansGUIJava 3DVirtual MachineCORBASecurityToolsGeneral
Java DirectoryOpen Source ProjectsSample Book ChaptersUser GroupsWeb Resources
Related Topics
Databases.NETMore Topics ...

Java Forum / General / September 2006

Tip: Looking for answers? Try searching our database.

Hibernate mapping problem with null in legacy data (in Oracle)

Thread view: 
ducnbyu - 07 Sep 2006 01:49 GMT
Hello,

I have a problem where I need to read legacy data that is not well
designed.  The table in question does not have a unique key.  Getting a
unique row requires knowing values for a non-unique indexed column and
an unindexed column.

The main problem is the unindexed column allows nulls and when a value
is not appropriate for the row, null is used in that column.  Making
matters worse the indexed column consists of the concatenation of 3
"intelligent" codes.

The obvious Hibernate mapping looks like this

   <class name="ReferenceTable"
       table="REFERENCE_TABLE">

       <composite-id>
           <key-property name="indexedColumn"
               column="INDEXED_COLUMN"/>
           <key-property name="unindexedColumn"
               column="UNINDEXED_COLUMN"/>
       </composite-id>

       <property ... />

   </class>

There is another class that defines a many-to-one to this

   <class name="detailTable"
       table="DETAIL_TABLE">

       <id name="theKey" column="THE_KEY" />

       <property ... />

       <many-to-one name="referenceTable"
           cascade="none" not-found="ignore">

           <formula> <!-- 1st key-property in ReferenceTable -->
               PART_1 || PART_2 || PART_3
           </formula>

           <column name="foreignUnindexedColumn" /> <!-- 2nd -->

       </many-to-one>

   </class>

This works fine when foreignUnindexedColumn contains a non-null value.

However, Oracle does not allow NULL in comparison expressions such that

   SELECT * FROM DUAL WHERE NULL = NULL;

returns no rows.

So when foreignUnindexedColumn contains null, Oracle returns no rows.
This is because the hibernate generated SQL looks something like
this...

SELECT ... FROM REFERENCE_TABLE
WHERE INDEXED_COLUMN = ?
AND UNINDEXED_COLUMN = ?

What I need is the above SQL to be executed when foreignUnindexColumn
contains a non-null and for the following SQL to be used when
foreignUnindexedColumn contains NULL...

SELECT ... FROM REFERENCE_TABLE
WHERE INDEXED_COLUMN = ?
AND UNINDEXED_COLUMN IS NULL

It is my impression that Hibernate was designed for well formed data
structures with some concession here and there for messy legacy data.
Are there any hibernate mappings that could handle this situation.  It
would be nice if this could be solved entirely via mapping.  This is
for reading only, I'm not doing any updates to these tables through
hibernate.

Any advice is greatly appreciated.
kafkasbug@gmail.com - 07 Sep 2006 04:01 GMT
I am by no means an expert in SQL, but if you need to manipulate the
data during retrieval, and you want to try and solve this problem via
mapping files, then your best bet would be to use the "where" attribute
of the <class> element in the mapping file.  This should allow you to
set conditions during the retrieval of the records in this table.

so...

>     <class name="ReferenceTable"
>         table="REFERENCE_TABLE" where="[SQL code]">
[quoted text clipped - 9 lines]
>
>     </class>

Dunno if that helps...

> Hello,
>
[quoted text clipped - 78 lines]
>
> Any advice is greatly appreciated.
ducnbyu - 08 Sep 2006 01:42 GMT
> I am by no means an expert in SQL, but if you need to manipulate the
> data during retrieval, and you want to try and solve this problem via
[quoted text clipped - 19 lines]
>
> Dunno if that helps...

It helps in a big way!  The where= itself doesn't help but, as I'm
still learning Hibernate, you prompted me to take a close look at the
Class definition documentation and found the <subselect>.

So I did this and it works:

    <class name="ReferenceTable"
        table="REFERENCE_TABLE">
       <subselect>
           select indexed_column,
               coalesce(unindexed_column, ' ') as unindexed_column,
               field, ..., more_fields
           from reference_table
       </subselect>

        <composite-id>
            <key-property name="indexedColumn"
                column="INDEXED_COLUMN"/>
            <key-property name="unindexedColumn"
                column="UNINDEXED_COLUMN"/>
        </composite-id>

        <property ... />

    </class>

The generated SQL puts the subselect into an in-line view:

SELECT reference0_.indexed_column AS ind1_9_0_,
      reference0_.unindexed_column AS uni2_9_0_,
      reference0_.field AS fie3_9_0_, ...,
      reference0_.more_fields AS mor4_9_0_
 FROM
(SELECT indexed_column,
              COALESCE (unindexed_column, ' ') unindexed_column,
              field, ..., more_fields
         FROM refrence_table) reference0_
WHERE reference0_.indexed_column = ?
AND reference0_.unindexed_column = ?

Since unindexed_column is not indexed, peformance is not lost using it
in an expression.  The Explain Plan is correct too.  Thanks so much for
the lead you gave!


Free Magazines

Get these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...

Oracle MagazineNetwork ComputingComputer WorldBio-IT WorldeWeekInformation WeekInfosecurity
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2008 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.