用于字符串列表的Hibernate自定义用户类型仅适用于不可变实体

时间:2016-03-29 09:07:42

标签: java hibernate postgresql jpa spring-boot

这是一个使用JPA和PostgreSQL的春季启动应用程序 我试图在postgres表中保留一个字符串列表(或一个字符串数组)。

表格如下所示:

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

出现的问题是当我尝试使用自定义usertype注释字段时。

@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<String> testArray;
}

我收到的错误:No Dialect mapping for JDBC type: 2003

之前我使用过这个自定义用户类型,但仅限于不可变实体(视图)。

所以,这段代码可以运行

@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<String> testArray;
}

我认为它与@Subselect和@Immutable注释不允许对实体进行插入/更新/删除操作这一事实有关,使用@Table注释,我能够完成所有这些操作动作。

有这样问题的经验或类似工作吗?

这是自定义usertype类:

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<String> 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<String> castObject = (List<String>) 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<List<String>> returnedClass()
    {
        return (Class<List<String>>) Collections.<String> emptyList().getClass();
    }

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

0 个答案:

没有答案