摘要
数据库:SQL server
开发环境:JDK1.8
错误编码:HHH000091: Expected type: java.lang.Long, actual value: java.math.BigInteger
在开发过程中,创建了一个Long类型的字段,在测试阶段,查询数据库时,报以下异常:
HHH000091: Expected type: java.lang.Long, actual value: java.math.BigInteger
[org.hibernate.property.BasicPropertyAccessor]HHH000091: Expected type: java.lang.Long, actual value: java.math.BigInteger
org.hibernate.PropertyAccessException: IllegalArgumentException occurred while calling setter of User.insertTime
at org.hibernate.property.BasicPropertyAccessor$BasicSetter.set(BasicPropertyAccessor.java:119)
at org.hibernate.transform.AliasToBeanResultTransformer.transformTuple(AliasToBeanResultTransformer.java:95)
at org.hibernate.hql.internal.HolderInstantiator.instantiate(HolderInstantiator.java:95)
at org.hibernate.loader.custom.CustomLoader.getResultList(CustomLoader.java:395)
at org.hibernate.loader.Loader.listIgnoreQueryCache(Loader.java:2263)
at org.hibernate.loader.Loader.list(Loader.java:2258)
at org.hibernate.loader.custom.CustomLoader.list(CustomLoader.java:331)
at org.hibernate.internal.SessionImpl.listCustomQuery(SessionImpl.java:1697)
at org.hibernate.internal.AbstractSessionImpl.list(AbstractSessionImpl.java:225)
at org.hibernate.internal.SQLQueryImpl.list(SQLQueryImpl.java:156)
解决方案:
方案1:修改字段set方法 ✔
修改字段set方法,因为long类型在自动生成数据库表结构的时候会生成为【bigint】类型,在使用SQLQuery查询时,最终还是调用set方法进行赋值,那么我直接调整set方法即可,但是这样代码不是很规范,所以不建议使用。
代码如下:
import org.hibernate.annotations.GenericGenerator;
import javax.persistence.*;
import java.math.BigInteger;
/**
* @author 崔
* @version 0.0.1
* @Date 2023/8/2 20:06
*/
@Entity
@Table(name = "t_s_user")
public class User implements java.io.Serializable {
@Id
@GeneratedValue(generator = "paymentableGenerator")
@GenericGenerator(name = "paymentableGenerator", strategy = "uuid")
@Column(name = "id", nullable = false, length = 32)
private String id;//id
private Long insertTime;//插入日期
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public Long getInsertTime() {
return insertTime;
}
/**
* 因为数据库查询绑定字段类型转换异常,修改入参
*
* @param insertTime
*/
public void setInsertTime(BigInteger insertTime) {
this.insertTime = insertTime.longValue();
}
}
方案2:修改字段类型✔
直接将实体类的字段类型修改为【BigInteger】类型。
注意:当字段修改为BigInteger类型后,实体类生成的字段类型为【numeric(19,2)】
我们需要通过【注解】来指定他的【数据库字段类型】(因为我的服务是部署到很多服务器上,之前的数据库表已经生成了bigint类型的字段,如果不指定的话会对之前的项目有影响,所以需要指定转换一下)。
但是Long类型就算用注解指定类型,也不生效,还是会报转换异常。
代码示例:
import org.hibernate.annotations.GenericGenerator;
import javax.persistence.*;
import java.math.BigInteger;
/**
* @author 崔
* @version 0.0.1
* @Date 2023/8/2 20:06
*/
@Entity
@Table(name = "t_s_user")
public class User implements java.io.Serializable {
@Id
@GeneratedValue(generator = "paymentableGenerator")
@GenericGenerator(name = "paymentableGenerator", strategy = "uuid")
@Column(name = "id", nullable = false, length = 32)
private String id;//id
@Column(name = "insertTime", columnDefinition = "bigint")//指定字段类型
private BigInteger insertTime;//插入日期
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public BigInteger getInsertTime() {
return insertTime;
}
public void setInsertTime(BigInteger insertTime) {
this.insertTime = insertTime;
}
}
这样写在查询的时候就不会出现转换异常的问题了。使用时可能注解会不起效果,可以放到吧注解放到get方法上面。
方案3:查询时添加字段转换❌
在网上看到了一个这个的方法,测试可以查询,但是查询出来的实体类结果中没有数据,也没有找到解决方案,就没有使用。
主要代码:sqlQuery.addScalar("insertTime", StandardBasicTypes.LONG);
public List<User> getListAllEntry() {
StringBuffer sqlBuffer = new StringBuffer("SELECT * FROM t_s_user WHERE 1=1 ");
SQLQuery sqlQuery = getSession().createSQLQuery(sqlBuffer.toString());
sqlQuery.addScalar("insertTime", StandardBasicTypes.LONG);
List<User> userList = sqlQuery.setResultTransformer(Transformers.aliasToBean(User.class)).list();
return userList;
}