Array with UserType in Hibernate and PostgreSQL –> MappingException

__________ HibernateSessionFactory.xml ___________________________

    <property name="hibernateProperties">
        <props>
            <!-- <prop key="hibernate.dialect">org.hibernate.dialect.PostgreSQLDialect</prop> -->
            <prop key="hibernate.dialect">com.test.model.PostgreSQLDialectArray</prop>              
            <prop key="hibernate.show_sql">true</prop>
            <prop key="hibernate.format_sql">true</prop>
            <prop key="hibernate.generate_statistics">false</prop>
            <prop key="hibernate.connection.pool_size">10</prop>
            <prop key="hibernate.archive.autodetection">class</prop>
            <prop key="hibernate.hbm2ddl.auto">create</prop>                
            <prop key="cache.provider_class">org.hibernate.cache.NoCacheProvider</prop>
        </props>
    </property>



    ______________ PostgreSQLDialectArray.java _______________________


package com.test.model;

import java.sql.Types;

public class PostgreSQLDialectArray extends org.hibernate.dialect.PostgreSQL82Dialect{

    public PostgreSQLDialectArray() {

        super();    

        System.out.println("Register Hibernate Type ... ");
        registerHibernateType(Types.ARRAY, "array");

        System.out.println("Register Column Type ... ");
        registerColumnType(Types.ARRAY, "integer[]");

    }
}



_____________ CustomArrayType.java ______________________________


package com.test.model;

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

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

 public class CustomArrayType implements UserType
 {

     protected static final int  SQLTYPE = java.sql.Types.ARRAY;

     private int[] toPrimitive(Integer[] array){
         int[] a = new int[array.length];
         for(int i = 0 ; i < array.length ; i++)
             a[i] = array[i];
         return a;
     }

     private Integer[] toObject(int[] array){
         Integer[] a = new Integer[array.length];
         for(int i = 0 ; i < array.length ; i++)
             a[i] = array[i];
         return a;
     }

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

     @Override
     public void nullSafeSet(final PreparedStatement statement, final Object object, final int i, SessionImplementor session) throws HibernateException, SQLException {
         System.out.println("test null safe set...");
         Connection connection = statement.getConnection();

         int[] castObject = (int[]) object;
         Integer[] integers = toObject(castObject);
         Array array = connection.createArrayOf("integer", integers);

         statement.setArray(i, array);
         System.out.println("test null safe set...");
     }

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

     @Override
     public Object deepCopy(final Object o) throws HibernateException {
         return o == null ? null : ((int[]) o).clone();
     }

     @Override
     public Serializable disassemble(final Object o) throws HibernateException {
         return (Serializable) o;
     }

     @Override
     public boolean equals(final Object x, final Object y) throws HibernateException {
         return x == null ? y == null : x.equals(y);
     }

     @Override
     public int hashCode(final Object o) throws HibernateException {
         return o == null ? 0 : o.hashCode();
     }

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

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

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

     @Override
     public int[] sqlTypes() {
         return new int[] { SQLTYPE };
     }

}



____________ MyClass.java ___________________________

package com.test.model;

import static javax.persistence.GenerationType.IDENTITY;

import java.io.Serializable;
import java.sql.Time;
import java.sql.Timestamp;
import java.sql.Types;
import java.util.Date;
import java.util.List;
import java.util.Set;

import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.EnumType;
import javax.persistence.Enumerated;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;
import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;
import javax.persistence.Table;

import org.hibernate.annotations.Type;

@Entity
@Table(name = "MyClass")
public class MyClass implements Serializable {

    private static final long serialVersionUID = -2520209406925143850L;

    @Id
    @GeneratedValue(strategy = IDENTITY)
    private Long id;

    @Type(type = "com.test.model.CustomArrayType")
    @Column(name = "arrayDay", nullable = true)
    private int[] arrayDay;           

    public Long getId() {
    return id;
    }

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

    public int[] getArrayDay() {
        return arrayDay;
    }

    public void setArrayDay(int[] arrayDay) {
        this.arrayDay = arrayDay;
    }  

}



______________ ArrayTypeTests.java ___________________________



package com.test;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

import com.test.model.MyClass;
import com.test.service.MyClassService;

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = { "classpath:application-context.xml" })
public class ArrayTypeTests implements ApplicationContextAware {

    @Autowired
    private MyClassService myClassService;

    public static ApplicationContext ctx;

    @Test
    public void test_() {
       System.out.println("Test junit");
    }

    @Test
    public void test_arrayDays() {

    System.out.println("\n - Start test_array - ");
    MyClass myClass = myClassService.getMyClassById(1L);
    if (myClass != null) {
        int[] array = myClass.getArrayDay();
        System.out.println("\n valor1:" + array[0]);
        System.out.println("\n valor2:" + array[1]);
        System.out.println("\n\n test_array OK ");
    } else {
        System.out.println("\n ERROR");
    }
    System.out.println("\n - End test_array - ");

    }

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
    ctx = applicationContext;
    }

}

Leave a Comment