News from March, 2007

  2007/03/01
Non-transactional Open Session In View
Last changed: Jul 31, 2008 10:49 by Auris Aume

Context:

Hibernate uses lazy initialization to load entities. E.g if some association is accessed after Hibernate session is closed we get LazyInitializationException. To solve this problem Hibernate team invented a pattern called Open Session In View. Spring offers OpenSessionInViewFilter that implement this pattern. This filter is used in many applications we have developed including AMS.

Problem:

Using OpenSessionInViewFilter solves issues with accessing uninitialized data from view. However the problem is that all intialization requests are made in a non-transactional manner. Hibernate will create new transaction for each initialization. What problems does this actually cause? First performance will be affected as DB needs to create much more transactions. Secondly atomacity of "transaction" is lost. How serious are these problems? I dare to say that not very serious so I don't think it is absolutely required to fix this for older applications but it's good thing to know when designing new applications.

Solution A:

Add another filter that will wrap the entire request inside a transaction. Downside is that we now have one big tx. Also we may discover the fact the tx needs to be rolled back after response has already been sent.

Solution B:

Improve solution A by changing tx attributes of business layer from propagation_required to propagation_requires_new. Now we can make the view rendering tx read-only and view rendering will be independent of business layer tx issues. Downside is that if service A is calling service B then we may not need to start new tx for B. One optimization here is using facades. These facades provide few methods that are specially tailored for presentation layer.

Resulting transactions:

To achieve this solution here is what we need:

  • simple filter that will be wrapped inside a read-only tx.
  • move tx management from services to facades.
  • change transaction attributes in facade to propagation_requires_new.
Posted at 01 Mar @ 2:51 PM by Ürgo Ringo | 10 Comments
  2007/03/14
CHAR(1) in Oracle

How to store boolean values to Oracle database table? Or perhaps a field that can have a few predefined values, like 'A', 'B', 'C', 'D'? A table in Oracle cannot have a data type BOOLEAN. So the first solution that comes to mind is using CHAR(1) data type, making it NOT NULL and limiting the allowed values with a CHECK constraint (remember that a CHECK constraint allows NULL values). Works almost always. Almost.

We had a problem once in Hansa project with a certain combination of VJDBC, Oracle JDBC driver and database configuration. When reading a CHAR(1) field we got a three character long string like "A " (letter 'A' followed by two spaces). Since the database character set was set to UTF-8, all character data type fields could contain three times more bytes. That is, three bytes were reserved for a CHAR(1) field; the same applied to VARCHAR2 fields too. Additionally, a CHAR field is always right padded with spaces to fill its max length (this does not depend on the database charset).

Our application connected to the database via VJDBC and started receiving three byte strings from fields that should by definition have just one character. When accessing the same data via SQLPlus or from Java program directly to database (without VJDBC), everything worked fine.

The solution was to always use VARCHAR2(1) instead of CHAR(1). In that case no right padding with spaces happens.

I have used CHAR(1) many times before in different applications without problems since it "should have worked as good as VARCHAR(1)". Well, it doesn't.

P.S. I don't remember what Oracle driver was used, OCI or thin. Doesn't matter though, I reckon.

Posted at 14 Mar @ 3:01 PM by Sven Filatov | 0 Comments