Sunday 28 September 2008

Do you know? Enum in Switch statements

You can now use an enum type in a "switch" statement, Earlier the switch expression had to be an int type.
Sun's Javac says -"enum switch case label must be the unqualified name of an enumeration constant.
So let's understand this with a simple example:

package com.doyou.know;

public class EnumInSwitch {

public static enum
Month { Jan, Feb, March }

public void printMonth(Month month) {

switch(month) {
case(Month.Jan): //Wrong: can not use parenthesis
System.out.println("January month..");

case Month.Feb: //Wrong Too: Enum reference can not be qualified
System.out.println("February month..");

case March: //RIGHT : this is how you do it ...
System.out.println("March month...");
}
}

public static void main(String[] args) {
new EnumInSwitch().printMonth(Month.March);
}
}


To summarize:

• In case statement the enum must be used without brackets.
• In case only the unqualified enum name (Jan, Feb, March) must be used.

Friday 26 September 2008

Hibernate short summary part-I, page 3

Read the Article Page-I, Page-II
Client Application:
Let us write a client application to persist our USER object... it would involve the following steps ...
1) Load the hibernate configuration and initiate Hibernate session factory. Hibernate session factory is responsible for providing the sessions to do the database interaction stuff. You can assume for the time the session factory to be equivalent of the JDBC connection pool and each session equivalent of JDBc connection ....

2) Once the session factory is instantiated ...get an active session from it..

3) We would create a User object which we want to save in the database ...

4) initiate a hibernate transaction, save the object and commit... :) we are done ...
In summary ... you need to learn some basic APIs on hibernate session.

Let us write the program now ...

Client.java:
package client;

import org.hibernate.*;
import org.hibernate.cfg.Configuration;
import com.entities.User;

public class Client {
public static void main(String[] args) {

try{

Configuration conf = new Configuration().configure();
//by default configure tries to search
//hibernate.cfg.xml step-I is done

SessionFactory sessionFactory = conf.buildSessionFactory();

//step_II
Session session =sessionFactory.openSession();

//step_III
User user = new User();
user.setName("Test User");
user.setAge(24);
//note that we did not set userId because thats auto incriment
Transaction t = session.beginTransaction();
session.save(user);
//save inserts the row in the database...
t.commit();

System.out.println("User inserted with Id : " + user.getUserId());
session.close();

}
catch(Exception e){
e.printStackTrace();
}
}
}

As I already said for the above program to compile and run properly, two set of Jar files have to placed properly in the application's class-path. One is the set of Jar files that are available within the Hibernate Ditribution, which is normally the <HIBERNATE_INSTALLATION>\lib, where <HIBERNATE_INSTALLATION> refers to the installation of the Hibernate.

Following jar files from the Hibernate distribution have to be maintained in the class-path of the application,

cglib2.jar
commons-collections
commons-Logging
dom4j.jar
ehcache.jar
jdbc2.0-stdext
jta.jar
log4j.jar
odmg.jar
xalan.jar
xerces.jar
xml-apis.jar

The other set of the jar files are for the Jdbc Driver.

The above code establishes a Configuration object by calling new Configuration().configure() which scans the classpath for the presence of hibernate.cfg.xml file. It then creates an instance of SessionFactory object with the details populated from the Configuration File by calling Configuration.buildSessionFactory(). A new Session object is then created for persisting objects by calling SessionFactory.openSession().

A new Java object called 'User' is populated with some test values and the object is persisted into the Session object within a transactional context by calling Session.beginTransaction() which marks the beginning of the transaction. Remember that Session.save(object) only marks the object to be persisted. After a successful save operation and transaction is committed by calling Transaction.commit(), which means that the object will be synchronized with the database.

Hibernate short summary part-I, page 2

Read the Article page-I here

The next step is to define the hibernate framework configuration file. This is a xml file where we essentially define the 2 things

1) Database details : which database we are going to use, whats are the connection urls, username password and all the database related configurations.

2) We tell the hibernate which are the mapping files. framework uses these mapping files to identify the mapping between the classes and the underlying database tables.

Let us name this configuration file as hibernate.cfg.xml
-----------------------------------------------------------------------
<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD//EN"
"http://hibernate.sourceforge.net/
hibernate-configuration-3.0.dtd">

<hibernate-configuration>
<session-factory>

<!-- Database connection settings -->
<property name="hibernate.dialect">
org.hibernate.dialect.OracleDialect
</property>
<property name="hibernate.connection.driver_class">
oracle.jdbc.OracleDriver
</property>
<property name="hibernate.connection.url">
jdbc:oracle:thin:@<host_name>:<port_number>:<database_name>
</property>
<property name="hibernate.connection.username">scott</property>
<property name="hibernate.connection.password">tiger</property>


<!-- Mapping files -->
<mapping resource="com/entities/User.hbm.xml"/>
</session-factory>
</hibernate-configuration>
------------------------------------------------------------------------------

The properties are explained below ...

hibernate.dialect :
This is the database specific attribute , hibernate identifies using this dialect how it will translate the queries... some of the example dialects are

Database SQL Dialect
SQL Server org.hibernate.dialect.SQLServerDialect
MySQL org.hibernate.dialect.MySQLDialect
Oracle org.hibernate.dialect.OracleDialect

hibernate.connection.driver_class : Identifies the JDBC driver class
hibernate.connection.url : Identifies the JDBC connection URL and the next 2 attributes are the database usernames and passwords.

< mapping-resource="com/entities/User.hbm.xml"/>> : tells the hibernate to load the mapping definition file, did you note the path given here is com/entities ?
because this where the mapping xml file is w.r.t to classpath context.

Now the next question is where we would keep the hibernate.cfg.xml ?
The essential answer is : it should be in the application classpath. you need to load this file while application initialization. so you should be aware of how to load this xml file.

So we are done with all the efforts. Lets summarize ..
we defined a table, a class , a mapping for class and table and hibernate configuration ...

The next step is to use the hibernate in our application to store and retrieve the Users. right?
We will write some sample program that would do these things ...

Thursday 25 September 2008

Hibernate short summary part-I

Hibernate addresses the one of the most important aspects of the Java applications, the data persistence. The data persistence facilities in the form of objects make it one of the most successful frameworks. I.e. as a Java programmer you see the underlying database tables as objects. Storing a row in the table for you is saving an object instance. The relation between the 2 tables for you is the references between the 2 objects, very simple indeed :). Guys believe me...if you are able to get these lines ...you have done the very first homework of learning the hibernate ... This is not a rocket science... have fun :)

This characteristic of hibernate is called the ORM [Object relational mapping] ORM is a piece of software/product for the representation and conversion of data between the database and the object-oriented programming language.

Another important feature which interests me most is that you need not worry about the database specific queries. e.g. the sql query to do some task X in oracle may be different from SQL Server, as a hibernate user I would not bother about it ... hibernate takes care of this for me .. how? We would come to it at appropriate time.

Things don't interest programmers unless they get their hands dirty with the codes and I would try to make things work for you in most simple way.

What you need to do next then?
1. Download and latest Hibernate. Hibernate is available for download at http://www.hibernate.org/
2. Create a simple java project in eclipse and Include the hibernate.jar file in the working directory. [don't know eclipse .. have coffee ..watch and learn here ]
3. Its good that you have some database installed.
4. Place your JDBC driver jar file for relevant to your database in the java project classpath.
5. You must know the connection parameters for your database. This could be the most frustrating thing for you to be able to run your hibernate application first time. Please note down your database connection URL, database name, port number, username, passwords etc. for more details read this

Next step is to create a simple USER table in the database as following ..

USER_ID <PK> int(10)
USER_NAME varchar(20)
USER_ PASSWORD varchar(10)
USER_ EMAIL varchar(20)

As I already said, we as a java programmer would view the underlying table as object ...so we would define a Class which would model the above table ... It should be straight forward isn't it ? This is gona be a simple java bean or Plain Old Java Objects... i.e. I would define the properties corresponding to the columns in the table.... how about the data types .. what should be the datatype for user_id ? :)

The only important thing is ...they should be compatible ... the fundamental rules are governed by java.sql.TYPES
here we go with the object definition ....

package com.entities

public class User {

private Long userId;

private String userName;
private String userPassword;
private String userEmail;

/** default constructor */
public User() {
}

public Long getUserId() {
return this.userId;
}

public void setUserId(Long id) {
this.userId = id;
}

public String getUserName() {
return this.userName;
}

public void setUserName(String userName) {
this.userName = userName;
}

public String getUserPassword() {
return this.userPassword;
}

public void setUserPassword(String userPassword) {
this.userPassword = userPassword;
}

public String getUserEmail() {
return this.userEmail;
}

public void setUserEmail(String userEmail) {
this.userEmail = userEmail;
}

}


Now, we have table ready..we have the class ready ...whats next ... ? I ask you a question ... how hibernate would determine ... which class refers which table .. which property of class maps to which column ? does this question makes sense ? of course it does ...

We are going to do next is to have a xml file ..which maps this stuff... and hibernate should be told to use this as the fundamental rules for mappig between the User class and USER table.... ok ?

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">

<hibernate-mapping>
<class name="com.entities.User" table="user">
<id column="USER_ID" name="user_id" type="java.lang.Long">
<generator class="increment"/>
</id>

<property column="USER_NAME" name="userName"/>
<property column="USER_PASSWORD" name="userPassword"/>
<property column="USER_EMAIL" name="userEmail"/>
</class>
</hibernate-mapping>

let us name this file user.hbm.xml .... you can name it the way you like it ... but as a hibernate style ...we would name the mapping files with .hbm.xml suffix.... now the next question ....where you would keep this file ?


Genuine answer is ...keep it anywhere it has to be in classpath :) ... but we generally keep them along the corresponding java beans classes ...
so I would keep it in com.entities package, along with User.java


Hibernate mapping documents are straightforward. I will describe the major elements in the mapping file.
1. <hibernate-mapping> element
The root element of the Hibernate mapping document is the <hibernate-mapping> element. This element has several optional attributes.

2. <class> element
The <Class> element maps the object with corresponding entity [table] in the database. In simple words, the <class> element maps a table with the corresponding class. The <hibernate-mapping> element allows you to nest several persistent <class> mappings, as shown above. It is, however, good practice to map only a single persistent class in one mapping file and name it after the persistent superclass; for example, User.hbm.xml.

3. <id> element

The <id> element defines the mapping from that property to the primary key column. The <id> element represents the primary key column and its associated attribute in the domain object. Mapped classes must declare the primary key column of the database table. Most classes also will have a JavaBeans-style property holding the unique identifier of an instance.

4. <generator> element

The optional <generator> child element names a Java class used to generate unique identifiers for instances of the persistent class. This is like a unique id generator ... Some commonly used generators are:

1. Increment. Generates auto increment numbers of type long, short, or int that are unique.
2. Sequence. Uses a predefined sequence from oracle, DB2, PostgreSQL, SAP DB. The returned identifier is of type long, short, or int.
3. Assigned. Lets the application assign an identifier to the object before. This is the default strategy if no <generator> element is specified.
4. Foreign. Uses the identifier of another associated object.

Let us defer their deep understanding to the knowledge refinement phase :))

5. <property> element
The <property> element declares a mapping between property of the class and the underlying column.

Friday 19 September 2008

Convert java Date time between timezones.

The standard way to specify your target timezone is GMT +/- hours minutes
e.g. for BST i can say "GMT+1"

String mytimeZone = "GMT+1";
GregorianCalendar abroad = new GregorianCalendar(TimeZone.getTimeZone(mytimeZone));
System.out.println(abroad.getTime());

//Format the timezone specific date display..
DateFormat df1 = DateFormat.getDateTimeInstance(DateFormat.FULL, DateFormat.FULL);
df1.setTimeZone(TimeZone.getTimeZone(mytimeZone));
System.out.println(df1.format(abroad.getTime()));

//Format to GMT time
df1.setTimeZone(TimeZone.getTimeZone("GMT"));
System.out.println(df1.format(abroad.getTime()));