-->
These old forums are deprecated now and set to read-only. We are waiting for you on our new forums!
More modern, Discourse-based and with GitHub/Google/Twitter authentication built-in.

All times are UTC - 5 hours [ DST ]



Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 1 post ] 
Author Message
 Post subject: Array with UserType in Hibernate and PostgreSQL
PostPosted: Wed Jan 09, 2013 7:19 am 
Newbie

Joined: Wed Jan 09, 2013 7:06 am
Posts: 1
Hi,
I am trying to write a class implementing UserType to deal with integer arrays in Hibernate/JPA but I cannot get it to work. I am using Hibernate 3.6.4.Final and postgresql 8.4-702.jdbc3.
I created a new Spring Roo project just to test it. Here are the different files (all java classes are located in the package test):

persistence.xml

Code:
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<persistence xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="2.0" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd">
  <persistence-unit name="persistenceUnit" transaction-type="RESOURCE_LOCAL">
    <provider>org.hibernate.ejb.HibernatePersistence</provider>
    <properties>
    <!--  <property name="hibernate.dialect" value="org.hibernate.dialect.PostgreSQLDialect"/> -->
    <property name="hibernate.dialect" value="test.PostgreSQLDialectArray"/>
    <!-- value="create" to build a new database on each run; value="update" to modify an existing database; value="create-drop" means the same as "create" but also drops tables when Hibernate closes; value="validate" makes no changes to the database -->
    <property name="hibernate.hbm2ddl.auto" value="create"/>
    <property name="hibernate.ejb.naming_strategy" value="org.hibernate.cfg.ImprovedNamingStrategy"/>
    <property name="hibernate.connection.charSet" value="UTF-8"/>
    <!-- Uncomment the following two properties for JBoss only -->
    <!-- property name="hibernate.validator.apply_to_ddl" value="false" /-->
    <!-- property name="hibernate.validator.autoregister_listeners" value="false" /-->
    </properties>
  </persistence-unit>
</persistence>


TestArray.java

Code:
package test;

import java.math.BigInteger;
import java.security.SecureRandom;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.roo.addon.javabean.RooJavaBean;
import org.springframework.roo.addon.serializable.RooSerializable;
import org.springframework.roo.addon.tostring.RooToString;

@RooJavaBean
@RooToString
@RooSerializable
public class TestArray {


     private static final long serialVersionUID = 1L;
     private SecureRandom random = new SecureRandom();


     public String nextSessionId()
     {
         return new BigInteger(130, random).toString(32);
     }

     public static void main(String[] args) {
         ApplicationContext context;
context = new ClassPathXmlApplicationContext("classpath:META-INF/spring/applicationContext.xml");
         int[] array = new int[1428];
         TestArray test = new TestArray();
         Blabla blabla = new Blabla();
         int nb = 1428;

         for(int i = 0 ; i < nb ; i++)
             array[i] = test.random.nextInt();
         //blabla.setArray(array);
         //blabla.persist();
         System.out.println("Done");
     }
}


Blabla.java


Code:
package test;

import org.hibernate.annotations.Type;
import org.springframework.roo.addon.entity.RooEntity;
import org.springframework.roo.addon.javabean.RooJavaBean;
import org.springframework.roo.addon.tostring.RooToString;

@RooJavaBean
@RooToString
@RooEntity
public class Blabla {

    @Type(type = "test.IntArrayUserType")
    @Column(length = 1428)
    private int[] array;
}


PostgreSQLDialectArray

Code:
package test;

import java.sql.Types;


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

    public PostgreSQLDialectArray() {
        super();
        registerHibernateType(Types.ARRAY, "array");
        registerColumnType(Types.ARRAY, "int[$l]" );
    }
}


IntArrayUserType.java (basically the same than in http://stackoverflow.com/questions/1647583/mapping-a-postgres-array-with-hibernate/1647660#1647660)

Code:
package test;
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 org.hibernate.HibernateException;
import org.hibernate.usertype.UserType;



public class IntArrayUserType 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, 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) 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 };
    }
}


Finally, the error that I get is the following:

Code:
2013-01-09 12:14:40,963 [main] ERROR org.hibernate.tool.hbm2ddl.SchemaExport - Unsuccessful: create table blabla (id int8 not null, array int[1428], version int4, primary key (id))
2013-01-09 12:14:40,963 [main] ERROR org.hibernate.tool.hbm2ddl.SchemaExport - ERREUR: erreur de syntaxe sur ou près de « array »
  Position: 40


Hibernate cannot create the table with the array of integers but I do not know what I did wrong.
Could you help me please?
Thank you in advance.


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 1 post ] 

All times are UTC - 5 hours [ DST ]


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Search for:
© Copyright 2014, Red Hat Inc. All rights reserved. JBoss and Hibernate are registered trademarks and servicemarks of Red Hat, Inc.