使用枚举作为参数的Hibernate查询

6

我正在尝试使用Hibernate(使用HSQLDB)进行查询,但运气不佳。查询代码如下:

Query query = session.createQuery("from "+tableName+" where CURRENCY = :currency");
query.setParameter("currency",currency);
List<ExchangeRate> list = query.list();

我一直遇到"Caused by: org.hsqldb.HsqlException: incompatible data type in conversion"的错误:
org.hibernate.exception.SQLGrammarException: could not execute query
    at org.hibernate.exception.internal.SQLExceptionTypeDelegate.convert(SQLExceptionTypeDelegate.java:82)
    at org.hibernate.exception.internal.StandardSQLExceptionConverter.convert(StandardSQLExceptionConverter.java:49)
    at org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:125)
    at org.hibernate.loader.Loader.doList(Loader.java:2529)
    at org.hibernate.loader.Loader.doList(Loader.java:2512)
    at org.hibernate.loader.Loader.listIgnoreQueryCache(Loader.java:2342)
    at org.hibernate.loader.Loader.list(Loader.java:2337)
    at org.hibernate.loader.hql.QueryLoader.list(QueryLoader.java:495)
    at org.hibernate.hql.internal.ast.QueryTranslatorImpl.list(QueryTranslatorImpl.java:357)
    at org.hibernate.engine.query.spi.HQLQueryPlan.performList(HQLQueryPlan.java:195)
    at org.hibernate.internal.SessionImpl.list(SessionImpl.java:1275)
    at org.hibernate.internal.QueryImpl.list(QueryImpl.java:101)
    at com.rockymountaineer.wsapi.db.test.ExchangeRateDAOTest.getRate(ExchangeRateDAOTest.java:27)
    at com.rockymountaineer.wsapi.db.test.ExchangeRateDAOTest.main(ExchangeRateDAOTest.java:39)
Caused by: java.sql.SQLSyntaxErrorException: incompatible data type in conversion
    at org.hsqldb.jdbc.JDBCUtil.sqlException(Unknown Source)
    at org.hsqldb.jdbc.JDBCUtil.throwError(Unknown Source)
    at org.hsqldb.jdbc.JDBCPreparedStatement.setParameter(Unknown Source)
    at org.hsqldb.jdbc.JDBCPreparedStatement.setBytes(Unknown Source)
    at org.hibernate.type.descriptor.sql.VarbinaryTypeDescriptor$1.doBind(VarbinaryTypeDescriptor.java:57)
    at org.hibernate.type.descriptor.sql.BasicBinder.bind(BasicBinder.java:93)
    at org.hibernate.type.AbstractStandardBasicType.nullSafeSet(AbstractStandardBasicType.java:280)
    at org.hibernate.type.AbstractStandardBasicType.nullSafeSet(AbstractStandardBasicType.java:275)
    at org.hibernate.param.NamedParameterSpecification.bind(NamedParameterSpecification.java:66)
    at org.hibernate.loader.hql.QueryLoader.bindParameterValues(QueryLoader.java:612)
    at org.hibernate.loader.Loader.prepareQueryStatement(Loader.java:1875)
    at org.hibernate.loader.Loader.executeQueryStatement(Loader.java:1836)
    at org.hibernate.loader.Loader.executeQueryStatement(Loader.java:1816)
    at org.hibernate.loader.Loader.doQuery(Loader.java:900)
    at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:342)
    at org.hibernate.loader.Loader.doList(Loader.java:2526)
    ... 10 more
Caused by: org.hsqldb.HsqlException: incompatible data type in conversion
    at org.hsqldb.error.Error.error(Unknown Source)
    at org.hsqldb.error.Error.error(Unknown Source)
    at org.hsqldb.types.NumberType.convertToDefaultType(Unknown Source)
    ... 24 more

这个类的注解如下:

@Column(name="CURRENCY", nullable=false)
public CurrencyType getCurrency() {
    return currency;
}

...并且Enum类型看起来像:

public enum CurrencyType {
    CAD, AUD, EUR, GBP, USD;    
    /**
     * @param currency
     * @return
     */
    public static CurrencyType getByCurrency(String currency) {
        if(currency!=null) {
            for(CurrencyType type : CurrencyType.values()) {
                if(type.name().equals(currency)) return type;
            }
        }
        return null;
    }
}

据我理解Hibernate文档,这应该完全可行 - 更不用说我目前能够使用其他Hibernate方法保存、编辑、删除、查询(按ID)对象 - 但“createQuery”仍然很难处理。
如果有人能帮忙,我真的非常感激! 谢谢, Alex
1个回答

8

...好的 - 我搞清楚了。如果有人也感到困惑,这是我发现的问题。默认情况下,表格使用序数值创建(在我的情况下是CurrencyType.ordinal()),所以当表格被创建时,列看起来像CURRENCY INTEGER NOT NULL

这不太理想,因为如果我更改枚举类型(即值的顺序),这将会破坏一切。好消息是,我可以通过在方法中添加@Enumerated(EnumType.STRING)强制它保存String值(CurrencyType.name()),这样它就会变成:

    @Enumerated(EnumType.STRING)
    @Column(name="CURRENCY", nullable=false)
    public CurrencyType getCurrency() {
        return currency;
    }

现在需要重新输入所有的数据。


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