Hibernate custom usertype for List of Strings only works with immutable entity
<p>This is a spring boot app using JPA, and PostgreSQL
I am trying to persist a list of Strings (or an array of Strings) in a postgres table.</p>

<p>The table looks something like this:</p>

<pre><code> CREATE TABLE test_table (
  id BIGSERIAL PRIMARY KEY NOT NULL,
  test_text text NOT NULL UNIQUE,
  test_array TEXT[]
);
</code></pre>

<p>The problem that occurs is when I try to annotate a field with my custom usertype.</p>

<pre><code>@Entity
@Table(name = "test_table")
public class TestTable extends BaseEntity {

  @Column(name = "test_text", nullable = false, unique = true)
  public String testText;

  @Type(type = "com.test.model.utils.StringListType")
  @Column(name = "test_array")
  public List&lt;String&gt; testArray;
}
</code></pre>

<p>The error that I get: <code>No Dialect mapping for JDBC type: 2003</code></p>

<p>I have worked with this custom usertype before, but only on immutable entities (views).</p>

<p>So, this code works</p>

<pre><code>@Entity
@Subselect("SELECT * FROM test_table")
@Immutable
public class TestView extends BaseEntity {

  @Type(type = "com.test.model.utils.StringListType")
  @Column(name = "test_array")
  public List&lt;String&gt; testArray;
}
</code></pre>

<p>I presume it has something to do with the fact that with the @Subselect and @Immutable annotations do not allow for insert/update/delete actions on the entity, where with the @Table annotation I am able to do all of those actions.</p>

<p>Any experience or similar work with a problem like this?</p>

<p>Here is the custom usertype class:</p>

<pre><code>public class StringListType implements UserType
{
    protected static final int SQLTYPE = java.sql.Types.ARRAY;

    @Override
    public Object nullSafeGet(final ResultSet rs, final String[] names,
            final SessionImplementor sessionImplementor, final Object owner) throws HibernateException,
            SQLException
    {
        Array array = rs.getArray(names[0]);
        List&lt;String&gt; stringList = Arrays.asList((String[]) array.getArray());
        return stringList;
    }

    @Override
    public void nullSafeSet(final PreparedStatement statement, final Object object, final int i,
            final SessionImplementor sessionImplementor) throws HibernateException, SQLException
    {
        Connection connection = statement.getConnection();

        @SuppressWarnings("unchecked")
        List&lt;String&gt; castObject = (List&lt;String&gt;) object;

        Array array = connection.createArrayOf("text", castObject.toArray());

        statement.setArray(i, array);
    }

    @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 : ((String[]) 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;
    }

    @SuppressWarnings("unchecked")
    @Override
    public Class&lt;List&lt;String&gt;&gt; returnedClass()
    {
        return (Class&lt;List&lt;String&gt;&gt;) Collections.&lt;String&gt; emptyList().getClass();
    }

    @Override
    public int[] sqlTypes()
    {
        return new int[] { SQLTYPE };
    }
}
</code></pre>