Hello,
I've been searching for a couple of days for a solution to my problem with no success yet, so I thought I'd ask here.
I'm using Hibernate 3.3.2-GA, jdk 1.5, the database is DB2 on AS400
I have 2 tables with a field of DECIMAL(30,9) that has been mapped as BigDecimal.
I must insert data in one of them, and in another phase, read that data and insert it in the other.
There is no problem with trying to insert a non zero value, as of yet. My problem is when I insert a new BigDecimal(0) in the first Table, everything seems fine.
When it comes time to read this and insert in the second table, I get the following error:
Code:
org.hibernate.type.BigDecimalType - could not bind value '0E-9' to parameter: 9; String index out of range: 10
I tried to set the decimalstringformat property in my datasource, but the driver for DB2 AS400 which is com.ibm.as400.access.AS400JDBCConnectionPoolDataSource does not accept it.
I made a UserType (not good at those) which didn't work. Here it is:
Code:
import java.io.Serializable;
import java.math.BigDecimal;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Types;
import org.hibernate.HibernateException;
import org.hibernate.usertype.UserType;
public class UserTypePlainBigDecimal implements UserType {
public Object assemble(Serializable arg0, Object arg1)
throws HibernateException {
// TODO Auto-generated method stub
return null;
}
public Object deepCopy(Object arg0) throws HibernateException {
return arg0;
}
public Serializable disassemble(Object arg0) throws HibernateException {
// TODO Auto-generated method stub
return null;
}
public boolean equals(Object arg0, Object arg1) throws HibernateException {
if (arg0 == arg1) {
return true;
} else if (arg0 == null) {
return false;
} else {
return ((BigDecimal)arg0).equals((BigDecimal)arg1);
}
}
public int hashCode(Object arg0) throws HibernateException {
// TODO Auto-generated method stub
return ((BigDecimal)arg0).hashCode();
}
public boolean isMutable() {
// TODO Auto-generated method stub
return false;
}
public Object nullSafeGet(ResultSet arg0, String[] arg1, Object arg2) throws HibernateException, SQLException {
BigDecimal result = arg0.getBigDecimal(arg1[0]);
return result == null ? new BigDecimal(0) : new BigDecimal(((BigDecimal)result).toPlainString());
}
public void nullSafeSet(PreparedStatement statement, Object value, int index) throws HibernateException, SQLException {
statement.setBigDecimal(index,new BigDecimal(((BigDecimal)value).toPlainString()));
}
public Object replace(Object arg0, Object arg1, Object arg2)
throws HibernateException {
// TODO Auto-generated method stub
return null;
}
public Class returnedClass() {
// TODO Auto-generated method stub
return null;
}
public int[] sqlTypes() {
return new int[] { Types.DECIMAL };
}
}
I am considering using this instead:
Code:
public void nullSafeSet(PreparedStatement statement, Object value, int index) throws HibernateException, SQLException {
BigDecimal valeur = new BigDecimal(0);
if (value != null && ((BigDecimal) value).toString().indexOf("E") < 0) {
valeur = (BigDecimal) value;
}
statement.setBigDecimal(index, valeur);
}
But I don't know if the only case I'll get an E in toString is with a Zero.
Also, the short notation is a pretty bad one for other functions such as comparisons for where clauses. Is there a way to make it read the database without giving me 0E-9?
Thanks in advance,
Daniel.