Pages

Thursday, December 27, 2007

An Interesting Reference to Google.com

Yesterday my mother made me a Christmas gift - a book. This book is called "Stress as an Asymmetric State. Natural Healing". Nice hardcover, approximately 125 pages. But on the very first page, where all the copyrights are listed I found something very strange to my mind.

I found the following. At the line 4 of the copyright page there's a reference to www.google.com. It says:
All the illustrative material comes from www.google.com and is adopted for this book


Pardon me, but I doubt that any trustworthy author would refer to a search engine in his/her text. Say, if you make a student project at university, will you refer to {yahoo|altavista|google|yandex}.com to make your text look authoritative??? I don't think so. I can think that the authors did not even know about this reference, but the respectful publisher should have thought twice before passing this one to production.

Tuesday, December 25, 2007

Hibernate Books Review

Java Persistence with Hibernate


Java Persistence with Hibernate was a good reference to me, but the book tries to be everything for everybody and this is what makes it a little hard to read. The book covers all the aspects of Hibernate framework in detail, starting from the ORM fundamentals up to conversational processing which is not found in any other Hibernate-related books.


Hibernate Quickly


As the name says, Hibernate Quickly is best suited as the introductory reference to Hibernate. The books follows the problem-solution pattern: at the beginning of each chapter, a bullet list of the topics is followed by the goals which a targeted by this chapter. This is what makes the book well-structured and easy to follow. I found a lot of easy to understand examples accompanied with good text explanations in this book and I think it is the best way to lean something new - by examples.

Wednesday, December 12, 2007

VARCHAR constants, Oracle 10g, and Oracle JDBC driver

Every day I have the luck to write some JDBC code @ work, and sometimes, in very specific conditions I face very strange errors. This post is about one problem that encountered while running a Java application, that queried a view in Oracle 10g database using Oracle JDBC driver v9.

In order to work with a complex database schema, a view was created to be used as an interface for a simple JDBC application. According to some specific business requirements, the view has to contain character constants - say, "if a column value is NULL then a query to the view should return 'X', otherwise, return the column's value". For this purpose, the view was created using the CASE/WHEN statements:

CREATE OR REPLACE VIEW view_name AS SELECT
CASE
WHEN column_name='X' THEN 'A'
ELSE 'B'
END
FROM DUAL

So, running a query "SELECT * FROM SOME_VIEW" was working OK and once we deployed the application in production we started to get some strange values from database. Instead of getting 'X' as it was defined, some whitespaces where added to the values, so that 'X' became 'X ', with two extra whitespaces, i.e. length 3 instead of length 1.

After some research we discovered that the system administrator was using Oracle JDBC driver v9 instead of a new one. Probably there are some "religious" reasons, why the version 9 should be preferred over version 10 for Oracle JDBC driver, especially with Oracle database version 10g. But the strange behavior of the application and the extra whitespaces problem had to be resolved to make the application work with the older driver.

Trimming every value that would be received from the view sounds like a stupid idea. So the first step was now to find out why the view constant was equipped with extra whitespaces. AFIAK, in Oralce 8i JDBC applications it was the common case that a CHAR type values were fetched with the whitespaces untrimmed, thus the obvious decision was made to seek for the view column type definition.

The metadata for a column's type is written in USER_TAB_COLUMNS and USER_COL_COMMENTS .

SELECT *
FROM user_tab_columns ut
, user_col_comments uc
WHERE ut.table_name = ? -- name of the created view
AND ut.table_name = uc.table_name
AND ut.column_name = uc.column_name
ORDER BY ut.column_id

So the column type was CHAR(3)! So the error could be fixed if the view could be created in such way that the problematic column could be VARCHAR2. A CASE/WHEN statement can be replaced with DECODE function, thus:

CREATE OR REPLACE VIEW view_name AS SELECT
DECODE(column_name, 'X', 'A', 'B')
FROM DUAL

The column type in the metadata table is now VARCHAR2(1)!

The strange thing is now actually why the driver version 10 was working correctly with the CHAR type. Correctly in sense of trimming the witespaces, but is it really correct behavior? (a rethorical question)

One special case was solved, but in some other views some constants were defined without any conditions:

CREATE VIEW some_view AS
SELECT
.....
'X'
.....
FROM table_name
WHERE condition

The value was still defined as CHAR in the metadata table. I don't know why, but I decided to describe the constant using TO_CHAR function with a random parameter, like this: TO_CHAR('X', 1). Apparently, it worked (!). The column was defined as VARCHAR2 now, but with maximum length of 4000. Is this some sort of undocumented feature of TO_CHAR function?! So far I knew that TO_CHAR function can be applied to a NUMBER or DATE type argument...

CREATE OR REPLACE VIEW view_name
AS SELECT TO_CHAR('A',1) FROM DUAL

The type issue was solved but in fact reserving 4000 symbols for the one-character-long constant is somewhat an overkill. Defining the constant via DECODE function solves this problem as well: DECODE('X', 'X', 'X'). So the type was now VARCHAR2(1).

CREATE OR REPLACE VIEW view_name
AS SELECT DECODE('A','A','A') FROM DUAL

After changing the views definitions the application started to work correctly with Oracle JDBC driver version 9.

The Morale
There's several things I have learnt with this issue:
1) always verify the view definition metadata in Oracle.
2) Oracle JDBC drivers are broken and behave oddly.
3) Oracle TO_CHAR function has some undocumented behavior.

Disqus for Code Impossible