我试图使用我的BigDecimal类通过hibernate将UserType数组映射到postgresql中,但是它引发了一个错误:“JDBC :2003没有方言映射”。我使用hibernate 5和PostgreSQL9.4-1206-jdbc 42。我的模型包括:
@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);
}
}我读过很多帖子,我的代码应该没问题。但有些地方不对劲。对不起,我的英语。
发布于 2016-10-26 11:03:35
最后,我找到了一个解决办法。问题是PostgreSQL9Dialect不知道数组类型。因此,通过创建这个类,我为它添加了自己的扩展:
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.dialect.PostgreSQL9Dialect
我已经键入了通往我自己班级的路径。
<prop key="hibernate.dialect">//path//.ArrayPostgreSQLDialect</prop>之后,hibernate在我的数据库中创建了类型为"numeric[]“的列。这就是全部。
发布于 2020-01-15 09:44:52
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 };
}}
https://stackoverflow.com/questions/40232570
复制相似问题