Need help with Hibernate? Read this first:
http://www.hibernate.org/ForumMailingli ... AskForHelp
Hibernate version: 3.1.3
Database: Oracle 10g
Basically the problem is that the SequenceGenerator class will return only values of type Long, Short, Int and String. I need it to return a BigDecimal.
The column type in the database is NUMBER( 30, 0), and this correctly maps to the Hibernate 'big_decimal' type as in the following:
<id name="uid" type="big_decimal">
<column name="UID" precision="30" scale="0" />
<generator class="sequence">
<param name="sequence">SEQ_UID</param>
</generator>
</id>
However when I run the code I get an exception
Caused by: org.hibernate.id.IdentifierGenerationException: this id generator generates long, integer, short or string
The problem is that the generator classes call the following piece of code in their generate() methods
Serializable result = IdentifierGeneratorFactory.get(rs, identifierType);
This method only checks if the return type is Long, Int, Short, or String and if not throws the above exception - here when a BigDecimal is required.
My current 'work around' - I have subclassed the SequenceGenerator class and have to add all the code from its generate() method while removing the call to IdentifierGeneratorFactory.get(rs, identifierType); where here I have to add my own implementation that checks for a BigDecimal return type. I do not feel at all comfortable with this 'work around' and am hoping there is a more robust solution.
This is basically what I am doing right now: note its almost identical to the existing SequenceGenerator class, I cannot call super.generate() as this throws the above exception, so I have to copy it and call my own BigDecimal test. not very DRY.
public class ExtendedSequenceGenerator extends SequenceGenerator {
public void configure( Type type, Properties params, Dialect dialect) throws MappingException {
...
}
public Serializable generate( SessionImplementor session, Object obj) throws HibernateException {
try {
PreparedStatement st = session.getBatcher().prepareSelectStatement( sql);
try {
ResultSet rs = st.executeQuery();
try {
rs.next();
//Serializable result = IdentifierGeneratorFactory.get( rs, identifierType );
Serializable result = this.get( rs, identifierType);
return result;
} finally {
rs.close();
}
} finally {
session.getBatcher().closeStatement( st);
}
} catch( SQLException sqle) {
throw JDBCExceptionHelper.convert( session.getFactory().getSQLExceptionConverter(),
sqle, "could not get next sequence value", sql);
}
}
private Serializable get( ResultSet rs, Type type) throws SQLException,
IdentifierGenerationException {
Class clazz = type.getReturnedClass();
if( clazz == Long.class) {
return new Long( rs.getLong( 1));
} else if( clazz == Integer.class) {
return new Integer( rs.getInt( 1));
} else if( clazz == Short.class) {
return new Short( rs.getShort( 1));
} else if( clazz == String.class) {
return rs.getString( 1);
} else if( clazz == BigDecimal.class) {
return rs.getBigDecimal( 1);
} else {
throw new IdentifierGenerationException(
"this id generator generates bigdecimal, long, integer, short or string");
}
}
}
Read this:
http://hibernate.org/42.html