2013-11-27 52 views
6

我沒有運氣讓hibernate(使用HSQLDB)查詢工作。查詢的代碼如下所示:使用枚舉作爲參數的休眠查詢

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

我始終得到 「:org.hsqldb.HsqlException:通過在引起不兼容的轉換數據類型」:

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; 
} 

...和枚舉類型的樣子:

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」被證明是固執的。

如果有人能幫助,我會誠摯地感謝! 乾杯,

亞歷

回答

8

... OK - 想通了。如果其他人感到困惑,這是我發現的。看起來默認情況下,表格是使用序號值創建的(在我的案例中爲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; 
    } 

...現在重新輸入所有數據。