Friday, October 2, 2009

I'm the database guy and I don't know where to find that value in the schema.

Here's an embarrasing story which illustrates just how ridiculously and unnecessarily complicated JPA/Hibernate makes your life. One of my teammates walked into my office with a printout of a web page and asked "Where do I find this value in the schema?" It was a simple concentration value attached to some library in the lab. The person who asked the question is very familiar with our schema. But she couldn't find the value. I looked in the two places I knew of where we store liquid concentration values, both turned up nothing.

No problem, I thought, I'll just look at the code to figure it out. Uh oh.

First I loaded up the HTML for Tapestry 4.0 (which, by the way, I loathe). Here's what it says:

<td align="right">
Concentration (nM):
</td>
<td align="left">
<span jwcid="@Insert" value="ognl:library.quantity.concentration" />
</td>

Okay, so I know ognl:library maps to some method called getLibrary() in the tapestry page, and I know (although the IDE doesn't) that the Library.html file talks to, by convention, LibraryPage.java. So I'll go look in that source code. Lo and behold, here's what I find there:
public abstract Library getLibrary();
Okay, drill into the Library class to find some sort of getQuantity() method.
Oh shit:

@Embedded
public SeqContentQuantity getQuantity()

What the hell does this mean? This is why I hate JPA/Hibernate: it takes a simple, well understood area of software engineering (mapping SQL queries and result sets to java types) and shits all over it. There's some dead-simple SELECT statement running somewhere, and all I want to know is what it is.

At this point I thought it might actually be faster to just start guessing at table and column names by inspecting Oracle's table metadata like so:
select
c.table_name,
c.column_name
from USER_TAB_COLUMNS c
where
c.column_name like '%CONC%'

Eventually I gave up the code analysis route and said fuck it, I'll just turn on hibernate SQL logging like so:

<property name="hibernate.show_sql" value="true"/>
<property name="hibernate.format_sql" value="true" />


in persistence.xml, along with
log4j.logger.org.hibernate=DEBUG
in the webapp's log4j.properties.

This drowned me in SQL, and grepping that much SQL is incredibly tedious, so I set a few breakpoints around the methods that retrieve the data. Only by stepping through the debugger and watching the SQL go by was I able to pinpoint what the actual table and column was. Bleah.

No comments:

Post a Comment