Saturday, May 3, 2014

Hibernate Interceptor Example

In order to use an Interceptor with our Session, we need to create a class that extends EmptyInterceptor.. Create a new class with name DataInterceptor.java. And now paste the following code:
package com.pkm.commands;

import java.io.Serializable;
import java.util.Iterator;
import org.hibernate.EmptyInterceptor;
import org.hibernate.Transaction;

public class DataInterceptor  extends EmptyInterceptor {
    private int updates = 0;
    private int creates = 0;
    private int loads = 0;
    private int deletes = 0;
    
    @Override
    public boolean onSave(Object entity, Serializable id, Object[] state, String[] propertyNames, org.hibernate.type.Type[] types) {
        System.out.println("onSave");
        creates++;
        return true;
    }
    
    // called on load events
    @Override
    public boolean onLoad(Object entity, Serializable id, Object[] state, String[] propertyNames, org.hibernate.type.Type[] types) {
        System.out.println("onLoad");
        loads++;
        return true;
    }

    @Override
    public boolean onFlushDirty(Object entity, Serializable id, Object[] currentState, Object[] previousState, String[] propertyNames, org.hibernate.type.Type[] types) {
        System.out.println("onFlushDirty");
        updates++;
        return false;
    }

    @Override
    public void onDelete(Object entity, Serializable id, Object[] state, String[] propertyNames, org.hibernate.type.Type[] types) {
        System.out.println("onDelete");
        deletes++;
    }

    //called before commit into database
    @Override
    public void preFlush(Iterator iterator) {
        System.out.println("preFlush");
    } 

    //called after committed into database
    @Override
    public void postFlush(Iterator iterator) {
        System.out.println("postFlush");
    }
    
    @Override
    public void afterTransactionCompletion(Transaction tx) {
        if ( tx.wasCommitted() ) {
            System.out.println("Creations: " + creates + ", Updates: " + 
                    updates + ", Loads: " + loads + ", Deletes: " + deletes);
        }
    }
}

These are the most basic methods that an Interceptor implements:
  • onSave : Called when you save an object. The object is not persisted yet.
  • onFlushDirty : Called when you update an object. The object is not persisted yet.
  • onLoad: Called when you read an object from database.
  • onDelete : Called when you delete an object. The object is not deleted from the database yet.
  • preFlush : Called before committing to the database.
  • postFlush :  Called after committing to the database.

We should also update HibernateUtil class:


package com.pkm.utils;

import com.pkm.commands.DataInterceptor;
import org.hibernate.service.ServiceRegistry;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
import org.hibernate.service.ServiceRegistryBuilder;

public class HibernateUtil {
    private static final SessionFactory sessionFactory = buildSessionFactory();
    private static ServiceRegistry serviceRegistry;
    
    private static SessionFactory buildSessionFactory() {
        try {
            Configuration configuration = new Configuration().setInterceptor(new DataInterceptor());
            configuration.configure();
            serviceRegistry = new ServiceRegistryBuilder().applySettings(configuration.getProperties()).buildServiceRegistry(); 
            return configuration.buildSessionFactory(serviceRegistry);
        } catch (Exception ex) {
            System.err.println("Initial SessionFactory creation failed." + ex);
            throw new ExceptionInInitializerError(ex);
        }
    }
 
    public static SessionFactory getSessionFactory() {
        return sessionFactory;
    }

    public static void shutdown() {
        // Close caches and connection pools
        getSessionFactory().close();
    }
}

Now create main java class file to test the Interceptor.


package com.pkm.commands;

import com.pkm.domains.User;
import com.pkm.utils.HibernateUtil;
import org.hibernate.Session;
import org.hibernate.Transaction;

public class TestInterceptor {
    @SuppressWarnings("unchecked")
    public static void main(String[] args) {
        Session session = null;
     Transaction transaction = null;
        try {
            session = HibernateUtil.getSessionFactory().openSession();
            transaction = session.beginTransaction();

            User user = new User(System.currentTimeMillis() + "@gmail.com", "Pritom", "Kumar Mondal");
            session.save(user);
            Long firstId = user.getId();

            user = new User(System.currentTimeMillis() + "@gmail.com", "Pritom", "Kumar Mondal");
            session.save(user);
            Long secondId = user.getId();
            
            user = (User) session.get(User.class, firstId);
            user.setFirstName("First name changed");
            session.save(user);
            
            user = (User) session.get(User.class, secondId);
            session.delete(user);
            
            user = (User) session.get(User.class, Long.parseLong("10"));
            user = (User) session.get(User.class, Long.parseLong("11"));
            user = (User) session.get(User.class, Long.parseLong("12"));
            
            transaction.commit();
        } catch (Exception ex) {
            if(transaction != null) {
                transaction.rollback();
            }
            System.err.println(ex.getMessage());
        } finally {
            if(session != null) {
                session.close();
            }
        }
    }
}

Output of Example:


onSave
Hibernate: insert into User (email, first_name, last_name) values (?, ?, ?)
onSave
Hibernate: insert into User (email, first_name, last_name) values (?, ?, ?)
onDelete
Hibernate: select user0_.id as id0_0_, user0_.email as email0_0_, user0_.first_name as first3_0_0_, user0_.last_name as last4_0_0_ from User user0_ where user0_.id=?
onLoad
Hibernate: select user0_.id as id0_0_, user0_.email as email0_0_, user0_.first_name as first3_0_0_, user0_.last_name as last4_0_0_ from User user0_ where user0_.id=?
onLoad
Hibernate: select user0_.id as id0_0_, user0_.email as email0_0_, user0_.first_name as first3_0_0_, user0_.last_name as last4_0_0_ from User user0_ where user0_.id=?
onLoad
preFlush
onFlushDirty
Hibernate: update User set email=?, first_name=?, last_name=? where id=?
Hibernate: delete from User where id=?
postFlush
Creations: 2, Updates: 1, Loads: 3, Deletes: 1

Download complete example

Friday, May 2, 2014

Iterate over each Entry in HashMap in Java Or loop Map to remove Entries

Example Class: HashMapIterator.java

package com.pkm.annotation;

import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

/**
 *
 * @author Pritom
 */
public class HashMapIterator {
    public static void main(String[] args) {
        Map map = new HashMap();
        map.put("key1", "Value 1");
        map.put("key2", "Value 2");
        map.put("key3", "Value 3");
        map.put("key4", "Value 4");
        map.put("key5", "Value 5");
        
        /* Using Iterator */
        System.out.println("Using Iterator");
        Iterator iterator = map.entrySet().iterator();
        while(iterator.hasNext()) {
            Map.Entry mapEntry = (Map.Entry) iterator.next();
            System.out.println("Key: " + mapEntry.getKey() + ", Value: " + 
                    mapEntry.getValue());
            if(mapEntry.getKey().toString().equals("key3")) {
                /* Removing without ConcurrentModificationException */
                iterator.remove(); 
            }
        }
        
        /* Using Direct Entry Set */
        System.out.println("\nUsing Direct Entry Set");
        for (Object entry : map.entrySet()) {
            Map.Entry mapEntry = (Map.Entry) entry;
            System.out.println("Key : " + mapEntry.getKey() + ", Value : "
                    + mapEntry.getValue());
        }
        
        /* Using Direct Key Set */
        System.out.println("\nUsing Direct Key Set");
        for (Object entry : map.keySet()) {
            System.out.println("Key : " + entry + ", Value : "
                    + map.get(entry));
        }
    }
}

Example Output:

Using Iterator
Key: key4, Value: Value 4
Key: key3, Value: Value 3
Key: key5, Value: Value 5
Key: key2, Value: Value 2
Key: key1, Value: Value 1

Using Direct Entry Set
Key : key4, Value : Value 4
Key : key5, Value : Value 5
Key : key2, Value : Value 2
Key : key1, Value : Value 1

Using Direct Key Set
Key : key4, Value : Value 4
Key : key5, Value : Value 5
Key : key2, Value : Value 2
Key : key1, Value : Value 1

Getting All Field Names and their corresponding values using Java Reflection

A Java Class: User.java

package com.pkm.reflection;

public class User {
    String firstName;    
    String lastname;
}

Example Runner Class: GetAllFieldsAndValues.java

package com.pkm.reflection;

import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.Map;

public class GetAllFieldsAndValues {
    public static void main(String[] args) {
        User user = new User();
        user.firstName = "Pritom";
        user.lastname = "Mondal";
        try {
            Map dataMap = GetAllFieldsAndValues.collectFieldValues(user);
            for (Object entry : dataMap.entrySet()) {
                Map.Entry mapEntry = (Map.Entry) entry;
		System.out.println("Key : " + mapEntry.getKey() + ", Value : "
			+ mapEntry.getValue());
            }
        } catch (Exception ex) {
            System.out.println("\n\nError: " + ex.getMessage());
        }
    }
    
    public static Map collectFieldValues(Object object) throws Exception {
        Map dataMap = new HashMap();
        Class obj = object.getClass();
        for (Field field : obj.getDeclaredFields()) {
            field.setAccessible(true);
            Object value = field.get(object);
            dataMap.put(field.getName(), value);
        }
        
        return dataMap;
    }
}

Example Output:

Key : lastname, Value : Mondal
Key : firstName, Value : Pritom

Java Custom Annotations Example

Annotation: ClassAnnotation.java


package com.pkm.annotation;

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

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE) //can use in class only.
public @interface ClassAnnotation {
    public enum Priority {
        LOW, MEDIUM, HIGH
     }

     Priority priority() default Priority.HIGH;

     String[] tags() default "";

     String name() default "Pritom";

     String date() default "02/05/2014";
}

Annotation: MethodAnnotation.java


package com.pkm.annotation;

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

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD) //can use in method only.
public @interface MethodAnnotation {
    public boolean enabled() default false; 
}

Annotation: FieldAnnotation.java


package com.pkm.annotation;

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

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD) //can use in field only.
public @interface FieldAnnotation {
    public boolean required() default false; 
    public boolean blank() default true;
    public int min() default 0;
    public int max() default 255;
}

Example Usage Of Custom Annotation: Example.java


package com.pkm.annotation;

@ClassAnnotation(name = "Pritom Kumar Mondal", priority = ClassAnnotation.Priority.MEDIUM, 
        tags = {"Pritom", "Kumar", "Mondal"})
public class Example {    
    @FieldAnnotation(required = true, blank = false, min = 10, max = 15)
    String name;
    
    @MethodAnnotation(enabled = true)
    void method1() {
        if(true) {
            System.out.println("True");
        } else {
            System.out.println("False");
        }
    }
    
    @MethodAnnotation(enabled = false)
    void method2() {
        if(true) {
            System.out.println("True");
        } else {
            System.out.println("False");
        }
    }
    
    @MethodAnnotation()
    void method3() {
        if(true) {
            System.out.println("True");
        } else {
            System.out.println("False");
        }
    }
}

Example Runner Class: RunExample.java


package com.pkm.annotation;

import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.lang.reflect.Method;

public class RunExample {
    public static void main(String[] args) throws Exception {
        RunExample runExample = new RunExample();
        Example example = new Example();
        example.name = "Pritom Kumar Mondal";
        try {
            RunExample.validate(example);
            System.out.println("\n\nInfo: Validation successful");
        } catch (Exception ex) {
            System.out.println("\n\nError: " + ex.getMessage());
        }
    }
    
    public static boolean validate(Object object) throws Exception {
        Class obj = object.getClass();
        /* Process @ClassAnnotation */
        if (obj.isAnnotationPresent(ClassAnnotation.class)) {
            Annotation annotation = obj.getAnnotation(ClassAnnotation.class);
            ClassAnnotation classAnnotation = (ClassAnnotation) annotation;
            
            System.out.printf("%nPriority :%s", classAnnotation.priority());
            System.out.printf("%nCreatedBy :%s", classAnnotation.name());
            System.out.printf("%nTags :");
            int tagLength = classAnnotation.tags().length;
            for (String tag : classAnnotation.tags()) {
                if (tagLength > 1) {
                    System.out.print(tag + " ||| ");
                } else {
                    System.out.print(tag);
                }
                tagLength--;
            }

            System.out.printf("%nDate :%s%n%n", classAnnotation.date());
        }
        
        /* Process @MethodAnnotation */
        for (Method method : obj.getDeclaredMethods()) {
            if (method.isAnnotationPresent(MethodAnnotation.class)) {
                Annotation annotation = method.getAnnotation(MethodAnnotation.class);
                MethodAnnotation methodAnnotation = (MethodAnnotation) annotation;
                if(methodAnnotation.enabled()) {
                    System.out.println(method.getName() +" is enabled");
                } else {
                    System.out.println(method.getName() +" is not enabled");
                }
            }
        }
        
        /* Process @FieldAnnotation */
        for (Field field : obj.getDeclaredFields()) {
            if (field.isAnnotationPresent(FieldAnnotation.class)) {
                Annotation annotation = field.getAnnotation(FieldAnnotation.class);
                FieldAnnotation methodAnnotation = (FieldAnnotation) annotation;
                field.setAccessible(true);
                Object value = field.get(object);
                
                /* Checking: required */
                if(methodAnnotation.required()) {
                    System.out.println(field.getName() +" is required with value: " + value);
                    if(value == null) {
                        throw new Exception(field.getName() + " is required");
                    }
                } else {
                    System.out.println(field.getName() +" is not required");
                }
                
                /* Checking: blank */
                if(!methodAnnotation.blank()) {
                    System.out.println(field.getName() +" not blank with value: " + value);
                    if(value == null || value.toString().trim().length() == 0) {
                        throw new Exception(field.getName() + " not blank");
                    }
                } else {
                    System.out.println(field.getName() +" can blank");
                }
                
                /* Checking: min */
                System.out.println(field.getName() +" min length: " + methodAnnotation.min());
                if(value != null && value.toString().trim().length() < methodAnnotation.min()) {
                    throw new Exception(field.getName() + " must min length: " + methodAnnotation.min());
                }
                
                /* Checking: max */
                System.out.println(field.getName() +" max length: " + methodAnnotation.max());
                if(value != null && value.toString().trim().length() > methodAnnotation.max()) {
                    throw new Exception(field.getName() + " must max length: " + methodAnnotation.max());
                }
            }
        }
        return true;
    }
}

Example Output:


Priority :MEDIUM
CreatedBy :Pritom Kumar Mondal
Tags :Pritom ||| Kumar ||| Mondal
Date :02/05/2014

method1 is enabled
method2 is not enabled
method3 is not enabled
name is required with value: Pritom Kumar Mondal
name not blank with value: Pritom Kumar Mondal
name min length: 10
name max length: 15


Error: name must max length: 15