UserType.class

package org.hibernate.usertype;
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.SharedSessionContractImplementor;

public interface UserType {
    int[] sqlTypes();
    Class returnedClass();
    boolean equals(Object var1, Object var2) throws HibernateException;
    int hashCode(Object var1) throws HibernateException;
    Object nullSafeGet(ResultSet var1, String[] var2, SharedSessionContractImplementor var3, Object var4) throws HibernateException, SQLException;
    void nullSafeSet(PreparedStatement var1, Object var2, int var3, SharedSessionContractImplementor var4) throws HibernateException, SQLException;
    Object deepCopy(Object var1) throws HibernateException;
    boolean isMutable();
    Serializable disassemble(Object var1) throws HibernateException;
    Object assemble(Serializable var1, Object var2) throws HibernateException;
    Object replace(Object var1, Object var2, Object var3) throws HibernateException;
}

StringArrayUserType.java

package uk.co.tandf.order.data;

import org.hibernate.engine.spi.SharedSessionContractImplementor;
import org.hibernate.usertype.UserType;
import java.io.Serializable;
import java.sql.*;

public class StringArrayUserType implements UserType {

    protected static final int[] SQL_TYPES = {Types.ARRAY};
    @Override
    public Object assemble(Serializable cached, Object owner) {
        return this.deepCopy(cached);
    }
    @Override
    public Object deepCopy(Object value) {
        return value;
    }
    @SuppressWarnings("unchecked")
    @Override
    public Serializable disassemble(Object value) {
        return (Serializable) value;
    }
    @Override
    public boolean equals(Object x, Object y) {
        if (x == null) {
            return y == null;
        }
        return x.equals(y);
    }
    @Override
    public int hashCode(Object x) {
        return x.hashCode();
    }
    @Override
    public Object nullSafeGet(ResultSet resultSet, String[] names, SharedSessionContractImplementor sharedSessionContractImplementor, Object o) throws SQLException {
        Array array = resultSet.getArray(names[0]);
        String[] stringArray = null;
        if (array != null)
            stringArray = (String[]) array.getArray();
        return stringArray;
    }
    @Override
    public void nullSafeSet(PreparedStatement st, Object value, int index, SharedSessionContractImplementor session) throws SQLException {
        if (value == null) {
            st.setNull(index, sqlTypes()[0]);
        } else {
            String[] castObject = (String[]) value;
            Array array = session.connection().createArrayOf("text", castObject);
            st.setArray(index, array);
        }
    }
    @Override
    public boolean isMutable() {
        return true;
    }
    @Override
    public Object replace(Object original, Object target, Object owner) {
        return original;
    }
    @Override
    public Class<String[]> returnedClass() {
        return String[].class;
    }
    @Override
    public int[] sqlTypes() {
        return new int[]{Types.ARRAY};
    }
}

TestClassDTO.java

package uk.co.tandf.order.repository.domain;

import com.fasterxml.jackson.annotation.JsonIdentityInfo;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.ObjectIdGenerators;
import com.tandf.orderentity.enums.FulfillmentStatus;
import com.tandf.orderentity.enums.ShipmentStatus;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.hibernate.annotations.DynamicInsert;
import org.hibernate.annotations.DynamicUpdate;
import org.hibernate.annotations.Type;

import javax.persistence.*;
import java.io.Serializable;
import java.util.Date;

@Entity
@Table(name = "test")
@DynamicInsert
@DynamicUpdate
@JsonIgnoreProperties({"hibernateLazyInitializer","handler"})
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class TestClassDTO implements Serializable {

    @Id
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "fulfillment_seq")
    @SequenceGenerator(sequenceName = "fulfillment_seq", allocationSize = 1, name = "fulfillment_seq")
    private Integer id;

    private String name;

    @Type(type = "uk.co.tandf.ordermanagement.data.StringArrayUserType")
    private String[] grantType;
}

Table creation query Hibernate: create table fulfillment (id integer not null, grant_type array, name varchar(255))

-------------------------------------------------------------------------------------------------------------

  • After checking with H2 database team, it's mentioned that Untyped ARRAY is valid only in H2 1.x.y. H2 2.0.202 and later versions have standard-compliant arrays, you need to specify base data type, such as CHARACTER VARYING(100) ARRAY etc.:
  • This is being taken care in Hibernate ORM, with 5.6.5.Final (or later version).
  • But, spring boot project still uses 5.6.4.Final, causing table creation failure.

Solution:- Upgrade Hibernate ORM, with 5.6.5.Final (or later version).

Comment From: arpitsingh11

@scottfrederick

Comment From: snicoll

Solution:- Upgrade Hibernate ORM, with 5.6.5.Final (or later version).

There is no need to report an issue in Hibernate here. We will upgrade to the latest available Hibernate version in due course. In the meantime you can upgrade the version in your project using the hibernate.version as explained in the reference documentation.