Hibernate 返回 BigIntegers 而不是 longs

20

这是我的发送者实体

@Entity
public class Sender {
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private long senderId;
...


...

    public long getSenderId() {
            return senderId;
    }
    
    public void setSenderId(long senderId) {
            this.senderId = senderId;
    }
}
    

当我尝试执行以下查询时:

StringBuilder query = new StringBuilder();
query.append("Select sender.* ");
query.append("From sender ");
query.append("INNER JOIN coupledsender_subscriber ");
query.append("ON coupledsender_subscriber.Sender_senderId = sender.SenderId ");
query.append("WHERE coupledsender_subscriber.Subscriber_subscriberId = ? ");
    
SQLQuery q = (SQLQuery) sessionFactory.getCurrentSession().createSQLQuery(query.toString());
q.setResultTransformer(Transformers.aliasToBean(Sender.class));
q.setLong(0, subscriberId);

return q.list();

出现以下错误:

ERROR: org.hibernate.property.BasicPropertyAccessor - HHH000123:在类be.gimme.persistence.entities.Sender中,属性senderId的setter方法发生了IllegalArgumentException异常

ERROR: org.hibernate.property.BasicPropertyAccessor - HHH000091:期望类型为long,实际值为java.math.BigInteger

这是因为类Sender中的senderId实际上是一个long而不是Hibernate返回的BigInteger。

我想知道在这种情况下最佳实践是什么,我应该使用BigIntegers作为id(似乎有些过度设计)?

我应该手动将查询结果转换为Sender类的对象吗(这将很遗憾)?还是我可以让Hibernate返回long id而不是BigInteger?或者有其他任何想法?

我正在使用Spring、Hibernate 4.1.1和MySQL。


你们的数据库中有大整数类型吗?确保你的对象映射正确。 - erencan
是的,它们都是BIGINT(20)类型。但这些是由Hibernate生成的表。 - Tristan Van Poucke
@erencan 我已经将我的发送者实体添加到问题中。但我认为长ID不应该映射为MySQL的BIGINT(20)(在MySQL中使用哪种其他类型会更正确?)。 - Tristan Van Poucke
好的,我已经在私有变量long senderId上添加了注解@Column(columnDefinition = "INT")。现在代码可以正常工作了。谢谢!你能把这个作为答案添加吗? - Tristan Van Poucke
是的,我会添加。不用谢。 - erencan
显示剩余3条评论
5个回答

34

在 Hibernate 中,“.list()”的默认值似乎是针对数字类型使用 BigInteger 返回类型。以下是一种解决方法:

session.createSQLQuery("select column as num from table")
  .addScalar("num", StandardBasicTypes.LONG).list();

2
是的,这里的问题在于默认的Hibernate行为。您还可以通过在构造函数中注册自定义SQL方言并调用registerHibernateType(Types.BIGINT,Hibernate.LONG.getName())来在全局级别上覆盖此行为。 - Hedley
如果在HQL查询中没有addScalar函数,那么应该使用什么替代方法,请告诉我。 - dom
@dom 不确定,也许可以将其作为一个新问题重新发布,并在此处添加链接 :) - rogerdpack

6

针对#Hedley的评论,如果你想全局修复这个问题,可以在SQLDialect构造函数中添加一行代码。在我的项目中,代码如下:

public PostgreSQLDialect() {
        super();
        registerHibernateType(Types.BIGINT, StandardBasicTypes.LONG.getName());
    }

5
在旧版本的Hibernate中,您可以使用
  session.createSQLQuery("select column as num from table")
 .addScalar("num", Hibernate.LONG).list();

3
对象数据库映射出现错误。此处存在一个强制类型转换异常,指示数据库字段为 BigInteger,但对象属性为 longBigInteger 是一个特殊的类,用于保存无限大小的整数值。此外,BigInteger 不能隐式地转换为 long。
为避免此错误,应将数据库字段更改为与 long 兼容的类型。将其更改为可以隐式转换为 longint 类型。请参见BigInteger

1

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接