nested exception is org.hibernate.PropertyAccessException: IllegalArgumentException occurred while calling setter of com.aebiz.b2bdelisource.model.SourceQuotationOrderModel.contractId
问题环境
mysql中contractId定义的是bigInt,hibernate环境的model中字段contractId是long类型,然后查询
String sql = "select * from aa ";
Query sqlQuery = getH4Session().createSQLQuery(sql)setResultTransformer(new AliasToBeanResultTransformer(Aa.class));
返回对象的时候报了这个错误
先说解决方案
方案一:
Query sqlQuery = getH4Session().createSQLQuery(sql).addScalar("contractId", StandardBasicTypes.LONG).setResultTransformer(new AliasToBeanResultTransformer(Aa.class));
对于这种方案,比较麻烦,而且还有一个非常难受的问题,就是加了这个contractId的数据类型,就只查这一个字段,忍不住爆粗口,每个都要写,但是有个好处就是在不知道这种处理在其他地方有没有被处理,比如别人自己处理了数据类型的情况下就不用去管
方案二:
自定义Dialect类,修改java.sql.Types.BIGINT对应的hibernate类型,然后hibernate使用自定义的Dialect。
public class LocalMySQL5InnoDBDialect extends MySQL5InnoDBDialect {
public LocalMySQL5InnoDBDialect() {
super();
registerHibernateType( Types.BIGINT, StandardBasicTypes.LONG.getName() );
}
}
原理解析
hibernate部分源码:
org.hibernate.loader.Loader.class类
/**
* Execute given <tt>PreparedStatement</tt>, advance to the first result and return SQL <tt>ResultSet</tt>.
*/
protected final ResultSet getResultSet(
final PreparedStatement st,
final RowSelection selection,
final LimitHandler limitHandler,
final boolean autodiscovertypes,
final SessionImplementor session)
throws SQLException, HibernateException {
try {
ResultSet rs = session.getTransactionCoordinator().getJdbcCoordinator().getResultSetReturn().extract( st );
rs = wrapResultSetIfEnabled( rs , session );
if ( !limitHandler.supportsLimitOffset() || !LimitHelper.useLimit( limitHandler, selection ) ) {
advance( rs, selection );
}
if ( autodiscovertypes ) {
autoDiscoverTypes( rs );
}
return rs;
}
catch ( SQLException sqle ) {
session.getTransactionCoordinator().getJdbcCoordinator().release( st );
throw sqle;
}
}
该方法执行PreparedStatement,通过autoDiscoverTypes( rs )方法自动匹配查询列的类型。
org.hibernate.loader.custom.JdbcResultMetadata类:
public Type getHibernateType(int columnPos) throws SQLException {
int columnType = resultSetMetaData.getColumnType( columnPos );
int scale = resultSetMetaData.getScale( columnPos );
int precision = resultSetMetaData.getPrecision( columnPos );
int length = precision;
if ( columnType == Types.CHAR && precision == 0 ) {
length = resultSetMetaData.getColumnDisplaySize( columnPos );
}
return factory.getTypeResolver().heuristicType(
factory.getDialect().getHibernateTypeName(
columnType,
length,
precision,
scale
)
);
}
org.hibernate.dialect.Dialect类
所以bigInt对应hibernate是bigInteger,所以重写Dialect或者加上StandardBasicTypes就能解决