PostgreSQL array object mapping through Hibernate

User defined datatype in hibernate

Posted on August 16, 2014
In this post I am providing code for PostgreSQL array datatype mapping through hibernate. All the explanation is same as my previous post Custom User Type Class
package com.vivekpatidar.postgres.demo;

import java.io.Serializable;
import java.sql.Array;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Types;

import org.hibernate.HibernateException;
import org.hibernate.engine.spi.SessionImplementor;
import org.hibernate.usertype.UserType;

public class IntegerArrayType implements UserType {

    @Override
    public Object assemble(Serializable cached, Object owner)
            throws HibernateException {
        return this.deepCopy(cached);
    }

    @Override
    public Object deepCopy(Object value) throws HibernateException {
        return value;
    }

    @Override
    public Serializable disassemble(Object value) throws HibernateException {
        return (Integer[]) this.deepCopy(value);
    }

    @Override
    public boolean equals(Object x, Object y) throws HibernateException {

        if (x == null) {
            return y == null;
        }
        return x.equals(y);
    }

    @Override
    public int hashCode(Object x) throws HibernateException {
        return x.hashCode();
    }

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

    @Override
    public Object nullSafeGet(ResultSet resultSet, String[] names,
            SessionImplementor session, Object owner)
            throws HibernateException, SQLException {
        Array array = resultSet.getArray(names[0]);
        Integer[] javaArray = (Integer[]) array.getArray();
        return javaArray;
    }

    @Override
    public void nullSafeSet(PreparedStatement statement, Object value,
            int index, SessionImplementor session) throws HibernateException,
            SQLException {
        Connection connection = statement.getConnection();
        Integer[] castObject = (Integer[]) value;
        Array array = connection.createArrayOf("integer", castObject);
        statement.setArray(index, array);
    }

    @Override
    public Object replace(Object original, Object target, Object owner)
            throws HibernateException {
        return original;
    }

    @Override
    public Class<Integer[]> returnedClass() {
        return Integer[].class;
    }

    @Override
    public int[] sqlTypes() {
        return new int[] { Types.ARRAY };
    }
}

Custom Dialect
package com.vivekpatidar.postgres.demo;

import java.sql.Types;
import org.hibernate.dialect.PostgreSQL9Dialect;

public class ArrayPostgreSQLDialect extends PostgreSQL9Dialect {

    public ArrayPostgreSQLDialect() {
        super();

        /**
         * For other type array you can change integer[] to that array type
         */

        this.registerColumnType(Types.ARRAY, "integer[]");
    }

}
UserContact Hibernate Entity Class
package com.vivekpatidar.postgres.demo;

import java.util.Arrays;

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;

import org.hibernate.annotations.Type;
import org.hibernate.annotations.TypeDef;
import org.hibernate.annotations.TypeDefs;

@Entity
@TypeDefs({ @TypeDef(name = "IntegerArrayObject", typeClass = IntegerArrayType.class) })
public class UserContact {

    @Id
    @GeneratedValue
    private Long id;

    @Type(type = "IntegerArrayObject")
    private Integer[] contact;

    public Long getId() {
        return id;
    }

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

    public Integer[] getContact() {
        return contact;
    }

    public void setContact(Integer[] contact) {
        this.contact = contact;
    }

    @Override
    public String toString() {
        return "UserContact [id=" + id + ", contact="
                + Arrays.toString(contact) + "]";
    }

}
Hibernate Session Factory Implementation class
package com.vivekpatidar.postgres.demo;

import java.util.Properties;

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

public class PostgresHibernateUtil {
    private static Configuration configuration = new Configuration();
    private static SessionFactory sessionFactory;
    private static Properties prop;

    private static SessionFactory buildSessionFactory() {
        try {

            prop = new Properties();

            String url = "127.0.0.1:5432/hstoreArrayCurddemo";
            prop.put("hibernate.dialect","com.vivekpatidar.postgres.demo.ArrayPostgreSQLDialect");
            prop.put("hibernate.connection.driver_class","org.postgresql.Driver");
            prop.put("hibernate.connection.url", "jdbc:postgresql://" + url);

            prop.put("hibernate.connection.username", "postgres");
            prop.put("hibernate.connection.password", "root");

            prop.put("hibernate.show_sql", "true");
            prop.put("hibernate.hbm2ddl.auto", "update");
            prop.put("hibernate.connection.isolation", "2");

            configuration.setProperties(prop);

            configuration.addAnnotatedClass(UserContact.class);

            return configuration.buildSessionFactory();
        } catch (Throwable ex) {
            System.out.println("Initital session factory build failed." + ex);
            throw new ExceptionInInitializerError(ex);
        }
    }

    public static SessionFactory getSessionFactory() {
        return buildSessionFactory();
    }

    public static Session getSession() {
        return sessionFactory.getCurrentSession();
    }

}