Java 休眠用户类型错误

Java 休眠用户类型错误,java,postgresql,hibernate,Java,Postgresql,Hibernate,我试图使用我的UserType类通过hibernate将BigDecimal数组映射到postgresql,但它抛出了一个错误:“没有JDBC类型的方言映射:2003”。 我正在使用hibernate 5和postgresql 9.4-1206-jdbc42。 我的模型包含: @Column(name = "prices") @Type(type = "com.hms.domain.customTypes.BigDecimalArrayType") private BigDecimal[] pr

我试图使用我的UserType类通过hibernate将BigDecimal数组映射到postgresql,但它抛出了一个错误:“没有JDBC类型的方言映射:2003”。
我正在使用hibernate 5和postgresql 9.4-1206-jdbc42。 我的模型包含:

@Column(name = "prices")
@Type(type = "com.hms.domain.customTypes.BigDecimalArrayType")
private BigDecimal[] prices;
这是我的UserData类:

import org.hibernate.HibernateException;
import org.hibernate.engine.spi.SharedSessionContractImplementor;
import org.hibernate.usertype.UserType;

import java.io.Serializable;
import java.math.BigDecimal;
import java.sql.*;


public class BigDecimalArrayType implements UserType {
    private static final int[] SQL_TYPES = {Types.ARRAY};

    public final int[] sqlTypes() {
        return SQL_TYPES;
    }

    public Class returnedClass() {
        return BigDecimal[].class;
    }

    public boolean equals(Object x, Object y) throws HibernateException {
        return x == y; 
    }

    public int hashCode(Object x) throws HibernateException {
        return x.hashCode();
    }

    public Object nullSafeGet(ResultSet rs, String[] names, SharedSessionContractImplementor session, Object owner) throws HibernateException, SQLException {
        Array array = rs.getArray(names[0]);
        BigDecimal[] javaArray = (BigDecimal[]) array.getArray();
        if (javaArray == null) { return new BigDecimal(0);}
        return javaArray;
    }

    public void nullSafeSet(PreparedStatement st, Object value, int index, SharedSessionContractImplementor session) throws HibernateException, SQLException {
        Connection connection = st.getConnection();
        BigDecimal[] bigDecimals = (BigDecimal[]) value;
        Array array = connection.createArrayOf("NUMERIC", bigDecimals);
        //Array array = session.connection().createArrayOf("NUMERIC", bigDecimals);
        if (null != array){
            st.setArray(index, array);
        } else {
            st.setNull(index, SQL_TYPES[0]);
        }
    }

    public Object deepCopy(Object value) throws HibernateException {
        return value == null ? null : ((BigDecimal[]) value).clone();
    }

    public boolean isMutable() {
        return true;
    }

    public Serializable disassemble(Object value) throws HibernateException {
        return (Serializable) this.deepCopy(value);
    }

    public Object assemble(Serializable cached, Object owner) throws HibernateException {
        return this.deepCopy(cached);
    }

    public Object replace(Object original, Object target, Object owner) throws HibernateException {
        return this.deepCopy(original);
    }
}
我读过很多帖子,似乎我的代码应该很好。但是有点不对劲。
附言:对不起我的英语。

最后,我找到了解决办法。 问题是PostgreSql9方言不知道数组类型。因此,我通过创建这个类为它添加了自己的扩展:

import org.hibernate.dialect.PostgreSQL9Dialect;    
import java.sql.Types;

public class ArrayPostgreSQLDialect extends PostgreSQL9Dialect {
    public ArrayPostgreSQLDialect() {
        super();
        /*
         *You can change the "numeric[]" type to any other you want.
        */
        this.registerColumnType(Types.ARRAY, "numeric[]");
    }
}
然后我更改了hibernate属性文件中的设置,而不是

org.hibernate.dialent.postgresql9dialent

我已经键入了我自己类的路径

<prop key="hibernate.dialect">//path//.ArrayPostgreSQLDialect</prop>
//path//.arraypostgresql方言
之后,hibernate在我的数据库中创建了类型为“numeric[]”的列。
就这些。

最后,我找到了一个解决方案。
import org.hibernate.HibernateException;
import org.hibernate.engine.spi.SessionImplementor;
import org.hibernate.usertype.UserType;

import java.io.Serializable;
import java.math.BigDecimal;
import java.sql.*;

public class BigDecimalArrayUserType implements UserType {

    protected static final int[] SQL_TYPES = { Types.ARRAY };

    @Override
    public Object assemble(Serializable arg0, Object arg1) throws HibernateException {
        return this.deepCopy(arg0);
    }

@Override
public Object deepCopy(Object arg0) throws HibernateException {
    return convert((Object[]) arg0);
}

@Override
public Serializable disassemble(Object arg0) throws HibernateException {
    return (BigDecimal[]) this.deepCopy(arg0);
}

@Override
public boolean equals(Object arg0, Object arg1) throws HibernateException {
    if (arg0 == null) {
        return arg1 == null;
    }
    return arg0.equals(arg1);
}

@Override
public int hashCode(Object arg0) throws HibernateException {
    return arg0.hashCode();
}

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

@Override
public Object nullSafeGet(ResultSet resultSet, String[] names, SessionImplementor session, Object owner)
        throws HibernateException, SQLException {
    /*
     * System.out.println(names[0]); System.out.println(resultSet.getArray(names[0]));
     */
    if (null == names[0]) {
        return null;
    }
    if (null == resultSet) {
        return null;
    }
    if (resultSet.getArray(names[0]) == null) {
        if (resultSet.wasNull()) {
            return null;
        }
        return new Long[0];
    } else {
        Array array = resultSet.getArray(names[0]);
        Object[] oldArr = (Object[]) array.getArray();
        return convert(oldArr);
    }
}

private BigDecimal[] convert(Object[] oldArr){
    if(oldArr==null){
        return null;
    }
    BigDecimal[] javaArray = new BigDecimal[oldArr.length];
    for(int i =0 ; i< oldArr.length; i++){
        javaArray[i]= new BigDecimal(String.valueOf(oldArr[i]));
    }
    return javaArray;
}

@Override
public void nullSafeSet(PreparedStatement statement, Object value, int index, SessionImplementor session)
        throws HibernateException, SQLException {
    Connection connection = statement.getConnection();
    if (value == null) {
        statement.setNull(index, SQL_TYPES[0]);
    } else {
        BigDecimal[] castObject = convert((Object[])value);

        Array array = connection.createArrayOf("numeric", castObject);
        statement.setArray(index, array);
    }
}

@Override
public Object replace(Object arg0, Object arg1, Object arg2) throws HibernateException {
    return arg0;
}

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

@Override
public int[] sqlTypes() {
    return new int[] { Types.ARRAY };
}
问题是PostgreSql9方言不知道数组类型。因此,我通过创建这个类为它添加了自己的扩展:

import org.hibernate.dialect.PostgreSQL9Dialect;    
import java.sql.Types;

public class ArrayPostgreSQLDialect extends PostgreSQL9Dialect {
    public ArrayPostgreSQLDialect() {
        super();
        /*
         *You can change the "numeric[]" type to any other you want.
        */
        this.registerColumnType(Types.ARRAY, "numeric[]");
    }
}
然后我更改了hibernate属性文件中的设置,而不是

org.hibernate.dialent.postgresql9dialent

我已经键入了我自己类的路径

<prop key="hibernate.dialect">//path//.ArrayPostgreSQLDialect</prop>
//path//.arraypostgresql方言
之后,hibernate在我的数据库中创建了类型为“numeric[]”的列。 仅此而已。

导入org.hibernate.hibernateeexception;
import org.hibernate.HibernateException;
import org.hibernate.engine.spi.SessionImplementor;
import org.hibernate.usertype.UserType;

import java.io.Serializable;
import java.math.BigDecimal;
import java.sql.*;

public class BigDecimalArrayUserType implements UserType {

    protected static final int[] SQL_TYPES = { Types.ARRAY };

    @Override
    public Object assemble(Serializable arg0, Object arg1) throws HibernateException {
        return this.deepCopy(arg0);
    }

@Override
public Object deepCopy(Object arg0) throws HibernateException {
    return convert((Object[]) arg0);
}

@Override
public Serializable disassemble(Object arg0) throws HibernateException {
    return (BigDecimal[]) this.deepCopy(arg0);
}

@Override
public boolean equals(Object arg0, Object arg1) throws HibernateException {
    if (arg0 == null) {
        return arg1 == null;
    }
    return arg0.equals(arg1);
}

@Override
public int hashCode(Object arg0) throws HibernateException {
    return arg0.hashCode();
}

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

@Override
public Object nullSafeGet(ResultSet resultSet, String[] names, SessionImplementor session, Object owner)
        throws HibernateException, SQLException {
    /*
     * System.out.println(names[0]); System.out.println(resultSet.getArray(names[0]));
     */
    if (null == names[0]) {
        return null;
    }
    if (null == resultSet) {
        return null;
    }
    if (resultSet.getArray(names[0]) == null) {
        if (resultSet.wasNull()) {
            return null;
        }
        return new Long[0];
    } else {
        Array array = resultSet.getArray(names[0]);
        Object[] oldArr = (Object[]) array.getArray();
        return convert(oldArr);
    }
}

private BigDecimal[] convert(Object[] oldArr){
    if(oldArr==null){
        return null;
    }
    BigDecimal[] javaArray = new BigDecimal[oldArr.length];
    for(int i =0 ; i< oldArr.length; i++){
        javaArray[i]= new BigDecimal(String.valueOf(oldArr[i]));
    }
    return javaArray;
}

@Override
public void nullSafeSet(PreparedStatement statement, Object value, int index, SessionImplementor session)
        throws HibernateException, SQLException {
    Connection connection = statement.getConnection();
    if (value == null) {
        statement.setNull(index, SQL_TYPES[0]);
    } else {
        BigDecimal[] castObject = convert((Object[])value);

        Array array = connection.createArrayOf("numeric", castObject);
        statement.setArray(index, array);
    }
}

@Override
public Object replace(Object arg0, Object arg1, Object arg2) throws HibernateException {
    return arg0;
}

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

@Override
public int[] sqlTypes() {
    return new int[] { Types.ARRAY };
}
导入org.hibernate.engine.spi.SessionImplementor; 导入org.hibernate.usertype.usertype; 导入java.io.Serializable; 导入java.math.BigDecimal; 导入java.sql.*; 公共类BigDecimalArrayUserType实现UserType{ 受保护的静态final int[]SQL_TYPES={TYPES.ARRAY}; @凌驾 公共对象汇编(可序列化arg0,对象arg1)引发HibernateException{ 返回此.deepCopy(arg0); } @凌驾 公共对象deepCopy(对象arg0)引发HibernateException{ 返回转换((对象[])arg0); } @凌驾 公共可序列化反汇编(对象arg0)引发HibernateException{ 返回(BigDecimal[])this.deepCopy(arg0); } @凌驾 公共布尔等于(对象arg0,对象arg1)引发HibernateException{ 如果(arg0==null){ 返回arg1==null; } 返回arg0.equals(arg1); } @凌驾 public int hashCode(对象arg0)引发HibernateeException{ 返回arg0.hashCode(); } @凌驾 公共布尔可交换(){ 返回true; } @凌驾 公共对象nullSafeGet(ResultSet ResultSet、字符串[]名称、SessionImplementor会话、对象所有者) 抛出HibernateeException、SQLException{ /* *System.out.println(名称[0]);System.out.println(resultSet.getArray(名称[0]); */ if(null==名称[0]){ 返回null; } if(null==resultSet){ 返回null; } if(resultSet.getArray(名称[0])==null){ if(resultSet.wasNull()){ 返回null; } 返回新长[0]; }否则{ Array Array=resultSet.getArray(名称[0]); Object[]oldArr=(Object[])array.getArray(); 返回转换(oldArr); } } 私有BigDecimal[]转换(对象[]oldArr){ if(oldArr==null){ 返回null; } BigDecimal[]javaArray=新的BigDecimal[oldArr.length]; for(int i=0;i
}

导入org.hibernate.hibernateeexception;
导入org.hibernate.engine.spi.SessionImplementor;
导入org.hibernate.usertype.usertype;
导入java.io.Serializable;
导入java.math.BigDecimal;
导入java.sql.*;
公共类BigDecimalArrayUserType实现UserType{
受保护的静态final int[]SQL_TYPES={TYPES.ARRAY};
@凌驾
公共对象汇编(可序列化arg0,对象arg1)引发HibernateException{
返回此.deepCopy(arg0);
}
@凌驾
公共对象deepCopy(对象arg0)引发HibernateException{
返回转换((对象[])arg0);
}
@凌驾
公共可序列化反汇编(对象arg0)引发HibernateException{
返回(BigDecimal[])this.deepCopy(arg0);
}
@凌驾
公共布尔等于(对象arg0,对象arg1)引发HibernateException{
如果(arg0==null){
返回arg1==null;
}
返回arg0.equals(arg1);
}
@凌驾
public int hashCode(对象arg0)引发HibernateeException{
返回arg0.hashCode();
}
@凌驾
公共布尔可交换(){
返回true;
}
@凌驾
公共对象nullSafeGet(ResultSet ResultSet、字符串[]名称、SessionImplementor会话、对象所有者)
抛出HibernateeException、SQLException{
/*
*System.out.println(名称[0]);System.out.println(resultSet.getArray(名称[0]);
*/
if(null==名称[0]){
返回null;
}
if(null==resultSet){
返回null;
}
if(resultSet.getArray(名称[0])==null){
if(resultSet.wasNull()){
返回null;
}
返回新长[0];
}否则{
Array Array=resultSet.getArray(名称[0]);
Object[]oldArr=(Object[])array.getArray();
返回转换(oldArr);
}
}
私有BigDecimal[]conv