Saturday, May 10, 2014

Display Hibernate Sql Parameter Values

Configure Log4j in Hibernate

Create a file named 'log4j.properties' under main project, where 'hibernate.cfg.xml' exists with following contents. This configuration will log sql in a file, the location you specified and also log in your project IDE console.


# Log everything. Good for troubleshooting  
log4j.logger.org.hibernate=INFO
# Log all SQL DML statements as they are executed
log4j.logger.org.hibernate.SQL=TRACE
# Log all JDBC parameters(TRACE|INHERITED);
log4j.logger.org.hibernate.type=TRACE
log4j.logger.org.hibernate.hql.ast.AST=info
# Log all SQL DDL statements as they are executed(INHERITED|WARN)
log4j.logger.org.hibernate.tool.hbm2ddl=INHERITED
log4j.logger.org.hibernate.hql=debug
log4j.logger.org.hibernate.cache=info
log4j.logger.org.hibernate.jdbc=debug   
# Log all second-level cache activity
log4j.logger.org.hibernate.cache=INHERITED
# Log all OSCache activity - used by Hibernate
log4j.logger.com.opensymphony.oscache=INHERITED
# Log transaction related activity
log4j.logger.org.hibernate.transaction=INHERITED
# Log all JDBC resource acquisition
log4j.logger.org.hibernate.jdbc=INHERITED
# Log all JAAS authorization requests
log4j.logger.org.hibernate.secure=INHERITED
# Root logger option  
log4j.rootLogger=INFO, CUSTOM_FILE, CUSTOM_STD_OUT  

# Define the file appender
log4j.appender.CUSTOM_FILE=org.apache.log4j.DailyRollingFileAppender
# Set the DatePattern (Every hour interval)
log4j.appender.CUSTOM_FILE.DatePattern='['yyyy-MM-dd-HH'].log'
# Set the DatePattern (Every minute interval)
#log4j.appender.CUSTOM_FILE.DatePattern='['yyyy-MM-dd-HH-mm'].log'
# Set the append to false, should not overwrite
log4j.appender.CUSTOM_FILE.Append=true
# Set the name of the file.
# It'll be created every hour/minute with different 
# filename(appnded with yyyy-MM-dd-HH/yyyy-MM-dd-HH-mm).
log4j.appender.CUSTOM_FILE.File=C:/tmp/debug.log
# Define the layout for file appender
log4j.appender.CUSTOM_FILE.layout=org.apache.log4j.PatternLayout
log4j.appender.CUSTOM_FILE.layout.conversionPattern= %d{HH:mm:ss} %m%n

# Direct log messages to stdout  
log4j.appender.CUSTOM_STD_OUT=org.apache.log4j.ConsoleAppender  
log4j.appender.CUSTOM_STD_OUT.Target=System.out  
log4j.appender.CUSTOM_STD_OUT.layout=org.apache.log4j.PatternLayout  
log4j.appender.CUSTOM_STD_OUT.layout.ConversionPattern=%d{ABSOLUTE} %5p %c{1}:%L - %m%n 
log4j.appender.CUSTOM_STD_OUT.layout.ConversionPattern=%d{ABSOLUTE} - %m%n

Execute following line of code when project start/run, before performing any CRUD operations:


ClassLoader loader = Thread.currentThread().getContextClassLoader();
URL url = loader.getResource("log4j.properties");
System.out.println(url);
PropertyConfigurator.configure(url);

You have to include log4j-1.2.16.jar in your project

When you perform query, output would be like this in your IDE consle:


/* When perform HQL */
10:30:29,149 - HQL: SELECT MIN(id) FROM com.pkm.domains.User

/* When perform SQL */
10:30:29,149 - SQL: select min(user0_.id) as col_0_0_ from User user0_
10:30:29,149 - throwQueryException() : no errors
10:30:29,191 - select min(user0_.id) as col_0_0_ from User user0_ limit ?
10:30:29,226 - Found [14] as column [col_0_0_]
10:30:29,228 - select user0_.id as id0_0_, user0_.date_updated as date2_0_0_, user0_.email as email0_0_, user0_.first_name as first4_0_0_, user0_.last_name as last5_0_0_, user0_.phone_number as phone6_0_0_, user0_.area_code as area7_0_0_ from User user0_ where user0_.id=?
10:30:29,230 - binding parameter [1] as [BIGINT] - 14
10:30:29,238 - Found [2014-05-10 10:23:08.0] as column [date2_0_0_]
10:30:29,238 - Found [pritomkucse@gmail.com] as column [email0_0_]
10:30:29,238 - Found [Pritom] as column [first4_0_0_]
10:30:29,239 - Found [Kumar Mondal] as column [last5_0_0_]

/* Update Query */
10:30:29,261 - update User set date_updated=?, email=?, first_name=?, last_name=?, phone_number=?, area_code=? where id=?
10:30:29,262 - binding parameter [1] as [TIMESTAMP] - Sat May 10 10:30:29 ALMT 2014
10:30:29,263 - binding parameter [2] as [VARCHAR] - pritomkucse@gmail.com
10:30:29,263 - binding parameter [3] as [VARCHAR] - Pritom
10:30:29,264 - binding parameter [4] as [VARCHAR] - Kumar Mondal
10:30:29,264 - binding parameter [7] as [BIGINT] - 14

Download complete example. This example also contains hibernate interceptor logic

Friday, May 9, 2014

Java Replace Camel Case String With Another String In That Place

MainClass.java

package com.pkm;

import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class MainClass {
    public static String mainString = "PritomKumarMondal";
    
    public static void main(String[] args) {
        System.out.println("Method: getString()");
        System.out.println("\t" + getString());
        System.out.println("Method: getString2()");
        System.out.println("\t" + getString2());
        System.out.println("Method: getString3()");
        System.out.println("\t" + getString3());
        System.out.println("Method: getString4()");
        System.out.println("\t" + getString4());
        System.out.println("Method: getString5()");
        System.out.println("\t" + getString5());
    }
    
    public static String getString() {
        System.out.println("\t" + MainClass.mainString);
        return MainClass.mainString.replaceAll("[^a-zA-Z0-9]+", "").replaceAll(
                String.format("%s|%s|%s",
                "(?<=[A-Z])(?=[a-z])",
                "(?<=[^A-Z])(?=[A-Z])",
                "(?<=[A-Za-z])(?=[^A-Za-z])"
                ),
            "."
        ).toLowerCase();
    }
    
    public static String getString2() {
        System.out.println("\t" + MainClass.mainString);
        String string = MainClass.mainString.replaceAll(
                String.format("%s",
                "(?=[A-Z])(?=[A-Z])"
                ),
            "."
        ).toLowerCase();
        string = string.replaceAll("[^a-zA-Z0-9.]+", "");
        return string.startsWith(".") ? string.substring(1) : string;
    }
    
    public static String getString3() {
        System.out.println("\t" + MainClass.mainString);
        return MainClass.mainString.replaceAll(
                String.format("%s",
                "(?<=[^A-Z])(?=[A-Z])"
                ),
            "."
        ).toLowerCase().replaceAll("[^a-zA-Z0-9.]+", "");
    }
    
    public static String getString4() {
        System.out.println("\t" + MainClass.mainString);
        String str1 = MainClass.mainString;
        str1 = str1.replaceAll("[A-Z]+", ".$0").toLowerCase().replaceAll("[^a-zA-Z0-9.]+", "");
        str1 = str1.startsWith(".") ? str1.substring(1) : str1;
        return str1;
    }
    
    public static String getString5() {
        System.out.println("\t" + MainClass.mainString);
        String str1 = MainClass.mainString;
        Pattern pattern = Pattern.compile("[A-Z]+");
        Matcher matcher = pattern.matcher(str1);
        StringBuffer output = new StringBuffer();
        while (matcher.find()) {
            matcher.appendReplacement(output, "." + matcher.group().toLowerCase());
        }
        matcher.appendTail(output);
        str1 = output.toString().replaceAll("[^a-zA-Z0-9.]+", "");
        return str1.startsWith(".") ? str1.substring(1) : str1;
    }
}

Output using: 'sUIKAm009Pritom KumarMondalUUID'


Method: getString()
 sUIKAm009Pritom KumarMondalUUID
 s.uika.m.009.p.ritom.k.umar.m.ondal.uuid
Method: getString2()
 sUIKAm009Pritom KumarMondalUUID
 s.u.i.k.am009.pritom.kumar.mondal.u.u.i.d
Method: getString3()
 sUIKAm009Pritom KumarMondalUUID
 s.uikam009.pritom.kumar.mondal.uuid
Method: getString4()
 sUIKAm009Pritom KumarMondalUUID
 s.uikam009.pritom.kumar.mondal.uuid
Method: getString5()
 sUIKAm009Pritom KumarMondalUUID
 s.uikam009.pritom.kumar.mondal.uuid

Output using: 'PritomKumarMondal'


Method: getString()
 PritomKumarMondal
 p.ritom.k.umar.m.ondal
Method: getString2()
 PritomKumarMondal
 pritom.kumar.mondal
Method: getString3()
 PritomKumarMondal
 pritom.kumar.mondal
Method: getString4()
 PritomKumarMondal
 pritom.kumar.mondal
Method: getString5()
 PritomKumarMondal
 pritom.kumar.mondal

Output using: 'Pritom KUMAR MonDAL'


Method: getString()
 Pritom KUMAR MonDAL
 p.ritom.kumarm.on.dal
Method: getString2()
 Pritom KUMAR MonDAL
 pritom.k.u.m.a.r.mon.d.a.l
Method: getString3()
 Pritom KUMAR MonDAL
 pritom.kumar.mon.dal
Method: getString4()
 Pritom KUMAR MonDAL
 pritom.kumar.mon.dal
Method: getString5()
 Pritom KUMAR MonDAL
 pritom.kumar.mon.dal

Java Regex to convert string to ascii code and ascii code to string back

MainClass.java


package com.pkm;

import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class MainClass {
    public static void main(String[] args) {
        String str1 = "&#40;=>THAI(คุณ), HINDI:(तुम मेरी हो), HANGERIO:(تو مال منی), CHINA:(您), ARBI(أنت), FARSI(شما)";
        System.out.println("\n\nOriginal :: " +str1);        
        Pattern pattern = Pattern.compile("([^\\x00-\\x7F])|([^A-Za-z0-9-_])");
        StringBuffer output = new StringBuffer();
        Matcher matcher = pattern.matcher(str1);
        while (matcher.find()) {
            String mString = matcher.group(0);
            String rep = String.format("[%d \\%s = %d]", 
                    mString.length(), mString,
                    (int) mString.charAt(0));
            String rep2 = String.format("&#%d;", (int) mString.charAt(0));
            matcher.appendReplacement(output, rep2);
        }
        matcher.appendTail(output);
        System.out.println("Output   :: " + output.toString());
        
        pattern = Pattern.compile("\\&\\#\\d{2,}\\;");
        matcher = pattern.matcher(output.toString());
        output = new StringBuffer();
        while (matcher.find()) {
            String mString = matcher.group(0);
            mString = mString.substring(2);
            mString = mString.substring(0, mString.length() - 1);
            mString = Character.toString((char) Integer.parseInt(mString));
            matcher.appendReplacement(output, mString);
        }
        matcher.appendTail(output);
        System.out.println("Output   :: " + output.toString());
    }
}

Output as follows:

Original :: &#40;=>THAI(คุณ), HINDI:(तुम मेरी हो), HANGERIO:(تو مال منی), CHINA:(您), ARBI(أنت), FARSI(شما)


Output   :: &#38;&#35;40&#59;&#61;&#62;THAI&#40;&#3588;&#3640;&#3603;&#41;&#44;&#32;HINDI&#58;&#40;&#2340;&#2369;&#2350;&#32;&#2350;&#2375;&#2352;&#2368;&#32;&#2361;&#2379;&#41;&#44;&#32;HANGERIO&#58;&#40;&#1578;&#1608;&#32;&#1605;&#1575;&#1604;&#32;&#1605;&#1606;&#1740;&#41;&#44;&#32;CHINA&#58;&#40;&#24744;&#41;&#44;&#32;ARBI&#40;&#1571;&#1606;&#1578;&#41;&#44;&#32;FARSI&#40;&#1588;&#1605;&#1575;&#41;


Output   :: &#40;=>THAI(คุณ), HINDI:(तुम मेरी हो), HANGERIO:(تو مال منی), CHINA:(您), ARBI(أنت), FARSI(شما)

Java code to convert string to ascii code and ascii code to string back

Tuesday, May 6, 2014

Hibernate HQL CRUD Example

HQLTest.java


package com.pkm.commands;

import com.pkm.domains.User;
import com.pkm.utils.HibernateUtil;
import java.util.List;
import org.hibernate.Query;
import org.hibernate.SQLQuery;
import org.hibernate.Session;
import org.hibernate.Transaction;

public class HQLTest {
    public static void main(String[] args) {
        Session session = null;
     Transaction transaction = null;
        try {
            session = HibernateUtil.getSessionFactory().openSession();
            transaction = session.beginTransaction();
            
            /* INSERT QUERY */
            SQLQuery sQLQuery = session.createSQLQuery("INSERT INTO "
                    + "User(email, first_name, last_name, phone_number, area_code) "
                    + "Values(:email, :first_name, :last_name, :phone_number, :area_code)");
            sQLQuery.setParameter("email", "pritomkucse@gmail.com");
            sQLQuery.setParameter("first_name", "Pritom");
            sQLQuery.setParameter("last_name", "Kumar");
            sQLQuery.setParameter("phone_number", "01727499452");
            sQLQuery.setInteger("area_code", 88);
            int insertResult = sQLQuery.executeUpdate();
            System.out.println("Insert Result: " + insertResult);
            
            /* SELECT QUERY*/
            Query query = session.createQuery("SELECT MIN(id) FROM User");
            query.setMaxResults(1);
            List queryList = query.list();
            System.out.println(queryList);
            
            query = session.createQuery("FROM User");
            query.setMaxResults(5);
            query.setReadOnly(true);
            queryList = query.list();
            for(Object object : queryList) {
                User user = (User) object;
                System.out.println("Email: " + user.getEmail() + ", First Name: " 
                        + user.getFirstName() + ", Last Name: " + user.getLastName() 
                        + ", Phone Area: " + user.getAreaCode() 
                        + ", Phone Number: " + user.getPhoneNumber());
            }
            
            /* UPDATE QUERY */
            User user = (User) queryList.get(0);
            query = session.createQuery("UPDATE User SET email=:email WHERE id = :id");
            query.setParameter("id", user.getId());
            query.setParameter("email", "sdfsdfsdf@gmail.com");
            int updateResult = query.executeUpdate();
            System.out.println("Update Result: " + updateResult);
            
            /* DELETE QUERY */
            user = (User) queryList.get(1);
            query = session.createQuery("DELETE FROM User WHERE id = :id");
            query.setParameter("id", user.getId());
            updateResult = query.executeUpdate();
            System.out.println("Delete Result: " + updateResult);
            
            transaction.commit();
        } catch (Exception ex) {
            if(transaction != null) {
                transaction.rollback();
            }
            System.out.println("Error: " + ex.getMessage());
        } finally {
            if(session != null) {
                session.close();
            }
        }
    }
}


You have to include antlr.jar to use HQL in your hibernate program.

Data saved in database as follows:


The java entity class used for this example:


package com.pkm.domains;

import java.util.Date;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;

@Entity
public class User implements java.io.Serializable {   
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "id", unique = true, nullable = false)
    private Long id;
    public void setId(Long id) {
        this.id = id;
    }
    public Long getId() {
        return this.id;
    }
    
    @Column(name = "email", unique = true, nullable = false, length = 100)
    private String email;
    public void setEmail(String email) {
        this.email = email;
    }
    public String getEmail() {
        return this.email;
    }
     
    @Column(name = "first_name", nullable = false)
    private String firstName;
    public void setFirstName(String firstName) {
        this.firstName = firstName;
    }
    public String getFirstName() {
        return this.firstName;
    }
     
    @Column(name = "last_name", nullable = true)
    private String lastName;
    public void setLastName(String lastName) {
        this.lastName = lastName;
    }
    public String getLastName() {
        return this.lastName;
    }
     
    @Column(name = "phone_number", nullable = false)
    private String phoneNumber;
    public void setPhoneNumber(String phoneNumber) {
        this.phoneNumber = phoneNumber;
    }
    public String getPhoneNumber() {
        return this.phoneNumber;
    }
     
    @Column(name = "area_code", nullable = true)
    private int areaCode;
    public void setAreaCode(int areaCode) {
        this.areaCode = areaCode;
    }
    public int getAreaCode() {
        return this.areaCode;
    }
    
    @Temporal(TemporalType.TIMESTAMP)
    @Column(name = "date_updated", unique = false, nullable = true, length = 100)
    private Date dateUpdated;
    public void setDateUpdated(Date dateUpdated) {
        this.dateUpdated = dateUpdated;
    }
    public Date getDateUpdated() {
        return this.dateUpdated;
    }
    
    public User() {
        this.dateUpdated = new Date();        
    }
}

Output as following


Hibernate: INSERT INTO User(email, first_name, last_name, phone_number, area_code) Values(?, ?, ?, ?, ?)
Insert Result: 1
Hibernate: select min(user0_.id) as col_0_0_ from User user0_ limit ?
[14]
Hibernate: select user0_.id as id0_, user0_.date_updated as date2_0_, user0_.email as email0_, user0_.first_name as first4_0_, user0_.last_name as last5_0_, user0_.phone_number as phone6_0_, user0_.area_code as area7_0_ from User user0_ limit ?
Email: sdfsdfsdf@gmail.com, First Name: Pritom, Last Name: Kumar Mondal, Phone Area: null, Phone Number: null
Email: 1399089957760@gmail.com, First Name: First name changed, Last Name: Kumar Mondal, Phone Area: null, Phone Number: null
Email: 1399089987865@gmail.com, First Name: Pritom, Last Name: Kumar Mondal, Phone Area: null, Phone Number: null
Email: 1399089987945@gmail.com, First Name: First name changed, Last Name: Kumar Mondal, Phone Area: null, Phone Number: null
Email: 1399090021059@gmail.com, First Name: Pritom, Last Name: Kumar Mondal, Phone Area: null, Phone Number: null
Hibernate: update User set email=? where id=?
Update Result: 1
Hibernate: delete from User where id=?
Delete Result: 1

Annotating Composite Custom Types in Hibernate

Two new classes are needed. The first is the class you want to use for the column(columns for composite user type).  In my case, I created a class Phone to store data in database.  Here's my class:
package com.pkm.utils;

public class Phone implements java.io.Serializable {
    private Integer areaCode = null;
    public Integer getAreaCode() {
        return areaCode;
    }
    public void setAreaCode(Integer areaCode) {
        this.areaCode = areaCode;
    }
    public void clearAreaCode() {
        this.areaCode = null;
    }
    
    private String phoneNum = null;
    public String getPhoneNum() {
        return phoneNum;
    }
    public void setPhoneNum(String phoneNum) {
        this.phoneNum = phoneNum;
    }
    
    public Phone() {
        
    }
    
    public Phone(String phoneNum, Integer areaCode) {
        this.phoneNum = phoneNum;
        this.areaCode = areaCode;
    }
    
    public Phone(String phoneNum) {
        this.phoneNum = phoneNum;
        this.areaCode = null;
    }
    
    @Override
    public String toString(){
        return areaCode + "-" + phoneNum;
   }
    
    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result + ((areaCode == null) ? 0 : areaCode.hashCode());
        result = prime * result + ((phoneNum == null) ? 0 : phoneNum.hashCode());
        return result;
    }
    
    @Override
    public boolean equals(Object obj) {
        if (this == obj)
            return true;
        if (obj == null)
            return false;
        if (getClass() != obj.getClass())
            return false;
        Phone other = (Phone) obj;
        if (areaCode == null) {
            if (other.areaCode != null)
                return false;
        } else if (!areaCode.equals(other.areaCode))
            return false;
        if (phoneNum == null) {
            if (other.phoneNum != null)
                return false;
        } else if (!phoneNum.equals(other.phoneNum))
            return false;
        return true;
    }
}


The factory class is produced by implementing (in the complex case) org.hibernate.usertype.CompositeUserType, you can also see simple case example. Documentation in this interface is pretty thin, but there are good examples available in the Hibernate distribution. Here's my implementation.

PhoneCompositeType.java

package com.pkm.utils;

import java.io.Serializable;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

import org.hibernate.HibernateException;
import org.hibernate.engine.spi.SessionImplementor;
import org.hibernate.type.Type;
import org.hibernate.usertype.CompositeUserType;

public class PhoneCompositeType implements CompositeUserType {
    @Override
    public String[] getPropertyNames() {
        return new String[] {"phoneNum", "areaCode"};
    }

    @Override
    public Type[] getPropertyTypes() {
        return new Type[]{
            org.hibernate.type.StandardBasicTypes.STRING,
            org.hibernate.type.StandardBasicTypes.INTEGER
        };
    }

    @Override
    public Object getPropertyValue(Object o, int i) 
            throws HibernateException {
        if(o == null) {
            return null;
        } else if(i == 0) {
            return ((Phone) o).getPhoneNum();
        } else if(i == 1) {
            return ((Phone) o).getAreaCode();
        }
        return null;
    }

    @Override
    public void setPropertyValue(Object o, int i, Object o1) 
            throws HibernateException {
        if(o != null) {
            if(i == 0) {
                ((Phone) o).setPhoneNum((String) o1);
            } else if(i == 1 && o1 != null) {
                ((Phone) o).setAreaCode((Integer) o1);
            }
        }
    }

    @Override
    public Class returnedClass() {
        return Phone.class;
    }

    @Override
    public boolean equals(Object o, Object o1) throws HibernateException {
        if(o == null && o1 == null) {
            return true;
        }
        if(o == null || o1 == null) {
            return false;
        }
        return o.equals(o1);
    }

    @Override
    public int hashCode(Object o) throws HibernateException {
        if(o != null) {
            return o.hashCode();
        }
        return 0;
    }

    @Override
    public Object nullSafeGet(ResultSet rs, String[] strings, 
    SessionImplementor si, Object o) 
            throws HibernateException, SQLException {
        String phoneNum = rs.getString(strings[0]);
        String areaCode = rs.getString(strings[1]);
        if(phoneNum != null) {
            Phone phone = new Phone(phoneNum);
            if(areaCode != null) {
                phone.setAreaCode(Integer.parseInt(areaCode));
            }
            return phone;
        }
        return null;
    }

    @Override
    public void nullSafeSet(PreparedStatement ps, Object o, int i, 
    SessionImplementor si) 
            throws HibernateException, SQLException {
        if(o != null) {
            ps.setString(i, ((Phone) o).getPhoneNum());
            if(((Phone) o).getAreaCode() != null) {
                ps.setInt(i + 1, ((Phone) o).getAreaCode());
            } else {
                ps.setString(i + 1, null);
            }
        } else {
            ps.setString(i, null);
            ps.setString(i + 1, null);
        }
    }

    @Override
    public Object deepCopy(Object o) throws HibernateException {
        if(o != null) {
            Phone newPhone = (Phone) o;
            return new Phone(newPhone.getPhoneNum(), newPhone.getAreaCode());
        }
        return null;
    }

    @Override
    public boolean isMutable() {
        return false;
    }

    @Override
    public Serializable disassemble(Object o, SessionImplementor si) 
            throws HibernateException {
        Object  deepCopy = deepCopy(o);
        if(!(deepCopy instanceof Serializable)) {
            return (Serializable) deepCopy;
        }
        return null;
    }

    @Override
    public Object assemble(Serializable srlzbl, 
    SessionImplementor si, Object o) 
            throws HibernateException {
        return deepCopy(srlzbl);
    }

    @Override
    public Object replace(Object o, Object o1, 
    SessionImplementor si, Object o2) 
            throws HibernateException {
        return deepCopy(o);
    }    
}


The core of this class is the two methods which get and set values associated with my new type: nullSafeSet and nullSafeGet. One key thing to note is that nullSafeGet is supplied with a list of all the column names mapped to the custom datatype in the current query. In my case, there's only one, but in complex cases, you can map multiple columns to one object (there are examples in the Hibernate documentation). The final piece of the puzzle is the annotation which tells Hibernate to use the new "Type" class to generate objects of your custom type by adding a new @Type annotation to the column. There would create two columns in the database as it is composite user type, not simple one. Data saved in database as follows:


Use new type as follows:


@Type(type = "com.pkm.utils.PhoneCompositeType")
@Columns(columns = {
    @Column(name = "phone_number"), 
    @Column(name = "area_code", nullable = true)
})
private Phone phone = new Phone();
public void setPhone(Phone phone) {
    this.phone = phone;
}
public Phone getPhone() {
    if(phone == null) {
        phone = new Phone();
    }
    return phone;
}

Use as follows


User user = (User) session.get(User.class, 1);
user.getPhone().setAreaCode(880);
user.getPhone().setPhoneNum("01727499452");

Output in my database as like (After save/update reading values from database):


Phone area: 880
Phone number: 01727499452