我一直在尝试在项目中的http://code.google.com/p/hibernate-sqlite/中使用SQLite的休眠方言,但是遇到了类似以下内容的问题...

    SQLQuery query = session
            .createSQLQuery("select id from collection where collection = (:collection_name);");

    query.setParameter("collection_name", collectionName);
    Integer collectionId = (Integer) query.uniqueResult();


我期望的是,如果查询没有匹配的行,则该collectionId将设置为null。我实际上得到的是一个例外,如下所示...

Exception in thread "main" org.hibernate.MappingException: No Dialect mapping for JDBC type: 0
    at org.hibernate.dialect.TypeNames.get(TypeNames.java:79)
    at org.hibernate.dialect.TypeNames.get(TypeNames.java:104)
    at org.hibernate.dialect.Dialect.getHibernateTypeName(Dialect.java:395)
    at org.hibernate.loader.custom.CustomLoader$Metadata.getHibernateType(CustomLoader.java:582)
    at org.hibernate.loader.custom.CustomLoader$ScalarResultColumnProcessor.performDiscovery(CustomLoader.java:508)
    at org.hibernate.loader.custom.CustomLoader.autoDiscoverTypes(CustomLoader.java:524)
    at org.hibernate.loader.Loader.getResultSet(Loader.java:1821)
    at org.hibernate.loader.Loader.doQuery(Loader.java:697)
    at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:259)
    at org.hibernate.loader.Loader.doList(Loader.java:2232)
    at org.hibernate.loader.Loader.listIgnoreQueryCache(Loader.java:2129)
    at org.hibernate.loader.Loader.list(Loader.java:2124)
    at org.hibernate.loader.custom.CustomLoader.list(CustomLoader.java:312)
    at org.hibernate.impl.SessionImpl.listCustomQuery(SessionImpl.java:1657)
    at org.hibernate.impl.AbstractSessionImpl.list(AbstractSessionImpl.java:165)
    at org.hibernate.impl.SQLQueryImpl.list(SQLQueryImpl.java:175)
    at org.hibernate.impl.AbstractQueryImpl.uniqueResult(AbstractQueryImpl.java:835)
    at uniqueResult line of code above.


查看了实际的方言,这并不完全令人惊讶,因为看起来JDBC类型0为null,并且该方言包含以下函数,其中注释了null映射...

public SQLiteDialect() {
    super();
    registerColumnType(Types.BIT, "integer");
                // ...lots more type registers...
    registerColumnType(Types.LONGVARBINARY, "blob");
    // registerColumnType(Types.NULL, "null");
    registerColumnType(Types.BLOB, "blob");
                // ...more column types and function registers...
}


不幸的是,取消注释映射为null的明显步骤似乎并没有改变行为。

有谁能指出我做错了什么,建议如何修复方言,或推荐任何好的资源来编写Hibernate方言?

最佳答案

有趣。因为Dialect找不到合适的休眠类型而不是列类型,所以引发了异常。您通常会使用registerHibernateType()方法进行注册。

但是,您不能使用Types.NULL来做到这一点,因为没有相应的Hibernate类型(NULL确实表示开头是“通用”类型)。而且我认为这不是问题的根源。

我从未使用过SQLite,但是您的查询是:

select id from collection where collection = (:collection_name)


看起来很好奇;那绝对不是标准的SQL。对于未映射的SQL查询,Hibernate尝试使用元数据自动检测结果的类型,在这种情况下,它不能(可能是因为SQLite元数据未提供正确的类型信息?)

可能的解决方法是:


使用SQLQuery.addScalar(alias, Type)明确指定结果的类型。
如果可能,将查询重写为HQL;您的实体映射将提供必要的类型信息。

关于java - Hibernate的SQLite方言错误,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/1635041/

10-09 13:28