Tuesday, March 20, 2012

Mapping enum java types as numbers by MyBatis

MyBatis provide EnumTypeHandler which allows to maps Java enumeration types to database as strings. String representation is good option, because values are directly readable from database, although there is one case when number representation is better. For example look at following enumeration:

Constant READ represent lowest possible access level. WRITE implicitly include READ access, and of course OWNER includes WRITE and READ accesses together. Now imagine SQL query which selects all documents where user specified by ID has access specified by accessLevel:

If access level is stored in database as string the query above isn't correct. But when we replace string representation by numbers, query works as expected.
READ1
WRITE2
OWNER3

How to alter standard behavior of MyBatis to map some java enumeration types as a string? Answer is: by implementing custom TypeHandler:

It would be nice if we can register the handler with specific java enumeration types like this:

But the configuration above is not valid yet! You have to implement your own EnumOrderTypeHandler and extend it for every java enumeration type:

and than register extended handler:

Friday, August 5, 2011

python, rabbitmq by pika

Did you already try "Hello world!" tutorial for python?
If so, then you probably notice strange message when run send.py on the console:
pika/callback.py:69: UserWarning: CallbackManager.add: Duplicate callback found for "0:Connection.CloseOk"
I was wondering where can be a problem and why the example from the tutorial produces that warning message, especially when the tutorial is on pages of RabbitMQ - messaging that just work. I focused on library pika.

The warning message is printed from pika/callback.py:68, so I added call stack prints to it:
And here is the result - two call stacks:

We can see on first call stack that the warning message is printed when a connection is closing. It looks like that something else already closed the connection.

Comparing the first call stack with the second call stack (which was actually printed before first one) explains where the problem is.

In the file pika/connection.py (in method close()) is method _on_close_ready() called twice:
  1. fist time indirectly (on line 453) when all channels are closed and
  2. secod time directly (on line 457) because after closing all channels is the _channels property always empty.

Solution is quite simple: see my commint
I hope that my change will be included in next version of pika and no more beginners of RabbitMQ will wonder why the messaging doesn't work smoothly in python as I did.