Hibernate Inheritance: Table Per Class hierarchy(Annotation)

Hi Guys, to my previous post i want to add annotation capability. There is not much change in the project structure but only minor changes are required. To the Person.java and Employee.java we add Annotation Capabilities, prior to adding annotations please add javaee-api-5.jar or javaee.jar in order to get the persistence annotation to your build path.

Person.java

/**
 * 
 */
package com.spark.hibernate.model;

import java.io.Serializable;

import javax.persistence.Column;
import javax.persistence.DiscriminatorColumn;
import javax.persistence.DiscriminatorType;
import javax.persistence.DiscriminatorValue;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.Inheritance;
import javax.persistence.InheritanceType;
import javax.persistence.Table;

/**
 * @author Sony
 * 
 */
@Entity
@Table(name="person")
@Inheritance(strategy=InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(discriminatorType=DiscriminatorType.STRING,name="discriminator")
@DiscriminatorValue(value="P")
public class Person implements Serializable {

	private int personId;
	private String firstName;
	private String lastName;
	
	public Person() {
		// TODO Auto-generated constructor stub
	}
	
	public Person(String firstName,String lastName) {
		this.firstName = firstName;
		this.lastName = lastName;
	}

	/**
	 * @return the personId
	 */
	@Id
	@GeneratedValue
	@Column(name="person_id")
	public int getPersonId() {
		return personId;
	}

	/**
	 * @param personId
	 *            the personId to set
	 */
	public void setPersonId(int personId) {
		this.personId = personId;
	}

	/**
	 * @return the firstName
	 */
	@Column(name="firstname")
	public String getFirstName() {
		return firstName;
	}

	/**
	 * @param firstName
	 *            the firstName to set
	 */
	public void setFirstName(String firstName) {
		this.firstName = firstName;
	}

	/**
	 * @return the lastName
	 */
	@Column(name="lastname")
	public String getLastName() {
		return lastName;
	}

	/**
	 * @param lastName
	 *            the lastName to set
	 */
	public void setLastName(String lastName) {
		this.lastName = lastName;
	}

}

Employee.java

/**
 * 
 */
package com.spark.hibernate.model;

import java.io.Serializable;
import java.util.Date;

import javax.persistence.Column;
import javax.persistence.DiscriminatorValue;
import javax.persistence.Entity;
import javax.persistence.Table;

/**
 * @author Sony
 * 
 */
@Entity
@Table(name="person")
@DiscriminatorValue(value="E")
public class Employee extends Person implements Serializable {

	private Date joiningDate;
	private String departmentName;
	
	public Employee() {
		// TODO Auto-generated constructor stub
	}
	
	public Employee(String firstName,String lastName,Date joiningDate,String departmentName) {
		super(firstName,lastName);
		this.joiningDate = joiningDate;
		this.departmentName = departmentName;
	}

	/**
	 * @return the joiningDate
	 */
	@Column(name="joining_date")
	public Date getJoiningDate() {
		return joiningDate;
	}

	/**
	 * @param joiningDate
	 *            the joiningDate to set
	 */
	public void setJoiningDate(Date joiningDate) {
		this.joiningDate = joiningDate;
	}

	/**
	 * @return the departmentName
	 */
	@Column(name="department_name")
	public String getDepartmentName() {
		return departmentName;
	}

	/**
	 * @param departmentName
	 *            the departmentName to set
	 */
	public void setDepartmentName(String departmentName) {
		this.departmentName = departmentName;
	}

}

Lets have little discussion about annotation in the code above:
The Person class is at the root of hierarchy. Hence we have used some annotations to make it as the root.

@Inheritance – Defines the inheritance strategy to be used for an entity class hierarchy. It is specified on the root of the entity class hierarchy.

@DiscriminatorColumn – Is used to define the discriminator column for the SINGLE_TABLE and JOINED inheritance mapping strategies. The strategy and the discriminator column are only specified in the root of an entity class hierarchy or sub hierarchy in which a different inheritance strategy is applied

If the @DiscriminatorColumn annotation is missing, and a discriminator column is required, the name of the discriminator column defaults to “DTYPE” and the discriminator type to DiscriminatorType.STRING.

@DiscriminatorValue – Is used to specify the value of the discriminator column for entities of the given type. The DiscriminatorValue annotation can only be specified on a concrete entity class. If the DiscriminatorValue annotation is not specified and a discriminator column is used, a provider-specific function will be used to generate a value representing the entity type. If the DiscriminatorType is STRING, the discriminator value default is the entity name.

The inheritance strategy and the discriminator column are only specified in the root of an entity class hierarchy or subhierarchy in which a different inheritance strategy is applied. The discriminator value, if not defaulted, should be specified for each entity class in the hierarchy.

after all these major changes small tweeks are required in hibernate.cfg.xml as follows:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
                                         "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
 <session-factory>
  <property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
  <property name="hibernate.connection.password">root</property>
  <property name="hibernate.connection.url">jdbc:mysql://localhost:3306/test</property>
  <property name="hibernate.connection.username">root</property>
  <property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
  <property name="hibernate.query.startup_check">true</property>
  <property name="hibernate.show_sql">true</property>
  <property name="hibernate.use_sql_comments">true</property>
  <property name="hibernate.format_sql">true</property>
  <mapping class="com.spark.hibernate.model.Person"/>
  <mapping class="com.spark.hibernate.model.Employee"/>
  <!-- <mapping resource="com/spark/hibernate/model/Person.hbm.xml"/> -->
 </session-factory>
</hibernate-configuration>

now the helper class changes as follows:

/**
 * 
 */
package com.spark.hibernate.util;

import org.hibernate.SessionFactory;
import org.hibernate.cfg.AnnotationConfiguration;
import org.hibernate.cfg.Configuration;

/**
 * @author Sony
 *
 */
public class HibernateUtil {

	private static SessionFactory sessionFactory;
	
	public static SessionFactory getSessionFactory(){
		
		//sessionFactory = new Configuration().configure().buildSessionFactory();
		sessionFactory = new AnnotationConfiguration().configure().buildSessionFactory();
		return sessionFactory;
	}
}

Now the changes are done your main class remains as it is, and the out put should be the same as the previous one.
Happy Coding πŸ™‚

How to create your own custom annotations in java and how to use it..PART-II

Hi in my previous post i have explained how to approach and understand over custom annotations using java, taking the support of meta annotations already given by java. Now i explain you how to code your own annotations. In my example i would like to explain how to inject object based on annotation.

Now i write a custom annotation “@AutoInject”, this annotation should be annotated on methods which will inject the object of particular class type as shown below

private EmployeeDTO employeeDTO;

public EmployeeDTO getEmployeeDTO() {
return employeeDTO;
}

@AutoInject
public void setEmployeeDTO(EmployeeDTO employeeDTO) {
this.employeeDTO = employeeDTO;
}

Now this code to get executed first we need to design our annotation i.e. @AutoInject as shown below:

/**
*
*/
package com.spark.custom.annotations;

import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
* @author Mantha Pavan Kumar
* injects the object to a getter method
*/
@Documented
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface AutoInject {

}

Now to process the annotation we have to write a class which will actually give the annotation behavior as below.

/**
*
*/
package com.spark.custom.annotations;

import java.beans.BeanInfo;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.io.File;
import java.lang.annotation.Annotation;
import java.lang.reflect.Method;

/**
* @author Mantha Pavan Kumar
*
*/
public class GenericAnnotations {
/**
* @param obj
* @return
*/
public static <T> T injectDependencies(final T obj) {
try {
Class clazz = obj.getClass();
BeanInfo beanInfo = Introspector.getBeanInfo(clazz);

for (PropertyDescriptor pd : beanInfo.getPropertyDescriptors()) {
Method writeMethod = pd.getWriteMethod();

if (writeMethod == null) {
continue;
}

Object existingVal = pd.getReadMethod().invoke(obj);
if (existingVal == null) {
for (Annotation annotation : writeMethod.getAnnotations()) {
if (annotation instanceof AutoInject) {
Class propertyType = pd.getPropertyType();
writeMethod.invoke(obj, propertyType.newInstance());
}
}
}
}
} catch (Exception e) {
// do something intelligent :)
}
return obj;
}

}

in this way you can code your own functional behavior of annotations, Happy Coding πŸ™‚ please find the below file for the entire code.
CustomAnnotations

How to create your own custom annotations in java and how to use it..PART-I

Hi All
Recently i have a thought why cant i create a custom annotations and use it, and below is the solution for it.

Lets look at what are annotations:

Annotations provide data about a program that is not part of the program itself. They have no direct effect on the operation of the code they annotate.Annotations have a number of uses, among them:

Information for the compiler β€” Annotations can be used by the compiler to detect errors or suppress warnings.
Compiler-time and deployment-time processing β€” Software tools can process annotation information to generate code, XML files, and so forth.
Runtime processing β€” Some annotations are available to be examined at runtime.

Annotations can be applied to a program’s declarations of classes, fields, methods, and other program elements.

Annotation Structure

There are two main components in annotations. First is annotation type and the next is the annotation itself which we use in the code to add meaning. Every annotation belongs to a annotation type.

Annotation Type:

public @interface {
method declaration;
}
eg: public @interface AutoInject{
public injectObject() default "";
}

Annotation type is very similar to an interface with little difference.

We attach β€˜@’ just before interface keyword.
Methods will not have parameters.
Methods will not have throws clause.
Method return types are restricted to primitives, String, Class, enums, annotations, and arrays of the preceding types.
We can assign a default value to method.

There are specific annotations which can only be used in the context of annotations. The annotations are target, retention, documented and inherited.

Meta Annotations

Annotations itself is meta information then what is meta annotations? As you have rightly guessed, it is information about annotation. When we annotate a annotation type then it is called meta annotation. For example, we say that this annotation can be used only for methods.

@Target(ElementType.METHOD)
public @interface MethodInfo { }

Annotation Types:
Documented: When a annotation type is annotated with @Documented then wherever this annotation is used those elements should be documented using Javadoc tool.

Inherited: This meta annotation denotes that the annotation type can be inherited from super class. When a class is annotated with annotation of type that is annotated with Inherited, then its super class will be queried till a matching annotation is found.

Retention: This meta annotation denotes the level till which this annotation will be carried. When an annotation type is annotated with meta annotation Retention, RetentionPolicy has three possible values:

@Retention(RetentionPolicy.RUNTIME)
public @interface Developer {
String value();
}

a.Class: When the annotation value is given as β€˜class’ then this annotation will be compiled and included in the class file.
b.Runtime: The value name itself says, when the retention value is β€˜Runtime’ this annotation will be available in JVM at runtime. We can write custom code using reflection package and parse the annotation. I have give an example below.
c.Source: This annotation will be removed at compile time and will not be available at compiled class.

Target:This meta annotation says that this annotation type is applicable for only the element (ElementType) listed. Possible values for ElementType are, CONSTRUCTOR, FIELD, LOCAL_VARIABLE, METHOD, PACKAGE, PARAMETER, TYPE.

in my next post i will explain how to code custom annotations and use them
Happy Coding πŸ™‚