You have told us about your proposed design, but you have not told us much about the reasons you chose it. I hope you have some pretty strong reasons for using this approach; In my experience this would be a very hard design to
test, debug and maintain.
1. Is Initializing DataSource (and making it as static ) have ne side effects?
2. Is static method approach recommended? Using public static methods forces you to compile-in the name of your "db access" class to every class which uses it. This makes it very hard to test or debug the rest of the code without a live database connection available - you can't substitute a "mock" database access class which simply returns known values for testing.
Using static initialisers is very dangerous. The JVM specification does not have much to say about the order in which initialisers are run, so you can't assume (for example) that your JNDI access classes have been initialised properly before your static initialiser runs. My rule of thumb for initialisers is to only ever use them for default values for primitives or simple objects such as Strings. Everything else should be done in a constructor or as needed.
Also, static initialisers are run at class-load time, so if your db access class is anywhere in your class path, every
Java program you run will try and open a JNDI connection and retrieve a DataSource whenever it starts. I find it hard to believe you actually want this strange behaviour.
3. Any performance penalty on getting connection from DataSource each time? This depends on your DataSource. If you use a DataSource implementation which pools connections, there will be very little overhead. If you use a naive implementation which actually closes connections, you could incur a large database performance hit.
4. What is best way of handling exceptions? Is it good practice to return null object? This entirely depends on what your clicnt code does with the returned value. In some situations it might be better to return a known "empty" object, or pass in a "default" object to be returned on error cases, or just pass on the exception. I can't really help you any more without knowing more about how this code will be used.
5. I am in notion that closing connection close all child objects such as Statements and Resultsets. Is this correct? I wouldn't rely on this. It is a common approach in pooled DataSources to override the "close" method of Connection to just return the connection to the pool. It's much better practice to always close things when you have finished with them.
6. And ne comments regarding other drawbacks of proposed design and enhancements that could be done to this design... Please help us by explaining why you feel that a static (non-Object-Oriented) solution has any benefits at all. The obvious, simple, solution would seem to be a regular class with a constructor which finds the DataSource, and other methods which use it. Can you give your reasons why did you not just choose this approach ?