`

Hibernate’s “Pure native scalar queries are not yet supported”

 
阅读更多

http://jdevelopment.nl/hibernates-pure-native-scalar-queries-supported/

 

In JPA one can define JPQL queries as well as native queries. Each of those can return either an Entity or one or more scalar values. Queries can be created on demand at run-time from a String, or at start-up time from an annotation (or corresponding XML variant seeWhere to put named queries in JPA?).

Of all those combinations, curiously Hibernate has never supported named native queries returning a scalar result, including insert, update and delete queries which all don’t return a result set, but merely the number of rows affected.

It’s a curious case, since Hibernate does support scalar returns in non-native named queries (thus a scalar return and named queries is not the problem), and it does support scalar returns in dynamically created native queries (thus scalar returns in native queries are not the problem either).

An example of this specific combination:

<named-native-query name="SomeName">
    <query>
        INSERT INTO
            foo
        SELECT
            *
        FROM
            bar
    </query>
</named-native-query>

If you do try to startup with such a query, Hibernate will throw an exception with the notorious message:

Pure native scalar queries are not yet supported

Extra peculiar is that this has been reported as a bug nearly 6 years(!) ago (see HHH-4412). In that timespan the advances in IT have been huge, but apparently not big enough to be able to fix this particular bug. “Not yet” certainly is a relative term in Hibernate’s world.

A quick look at Hibernate’s source-code reveals that the problem is withinorg.hibernate.cfg.annotations.QueryBinder, more specifically the bindNativeQuery method. It has the following outline:

public static void bindNativeQuery(org.hibernate.annotations.NamedNativeQuery queryAnn, Mappings mappings){
    if (BinderHelper.isEmptyAnnotationValue(queryAnn.name())) {
        throw new AnnotationException("A named query must have a name when used in class or package level");
    }
    NamedSQLQueryDefinition query;
    String resultSetMapping = queryAnn.resultSetMapping();
    if (!BinderHelper.isEmptyAnnotationValue(resultSetMapping)) {
        query = new NamedSQLQueryDefinition (
            // ...
        );
    }
    else if (!void.class.equals(queryAnn.resultClass())) {        
        // FIXME should be done in a second pass due to entity name?
        final NativeSQLQueryRootReturn entityQueryReturn =
            new NativeSQLQueryRootReturn (
                // ...
            );
    }
    else {
        throw new NotYetImplementedException( "Pure native scalar queries are not yet supported" );
    }
}

Apparently, the NamedNativeQuery annotation (or corresponding XML version), should either have a non-empty resultset mapping, or a result class that’s something other than void.

So, isn’t a workaround for this problem perhaps to just provide a resultset mapping, even though we’re not doing a select query? To test this, I tried the following:

<named-native-query name="SomeName" result-set-mapping="dummy">
    <query>
        INSERT INTO
            foo
        SELECT
            *
        FROM
            bar
    </query>
</named-native-query>
 
<sql-result-set-mapping name="dummy">
    <column-result name="bla" />
</sql-result-set-mapping>

And lo and behold, this actually works. Hibernate starts up and adds the query to its named query repository, and when subsequently executing the query there is no exception and the insert happens correctly.

Looking at the Hibernate code again it looks like this shouldn’t be that impossible to fix. It’s almost as if the original programmer just went out for lunch while working on that code fragment, temporarily put the exception there, and then after lunch completely forgot about it.

Until this has been fixed in Hibernate itself, the result-set-mapping workaround might be useful.

Arjan Tijms

 

 

注解方式:

@Entity(name="EmployeeEntity")
@Table (name="employee")

@SqlResultSetMapping(name="updateResult", columns = { @ColumnResult(name = "count")})

@NamedNativeQueries({
@NamedNativeQuery(
name	=	"updateEmployeeName",
query	=	"UPDATE employee SET firstName = ?, lastName = ? WHERE id = ?"
,resultSetMapping = "updateResult"
)
})

public class EmployeeEntity implements Serializable
{
//entity code
}
分享到:
评论

相关推荐

    Hibernate+中文文档

    16.1.1. 标量查询(Scalar queries) 16.1.2. 实体查询(Entity queries) 16.1.3. 处理关联和集合类(Handling associations and collections) 16.1.4. 返回多个实体(Returning multiple entities) 16.1.5. 返回非...

    hibernate3.2中文文档(chm格式)

    16.1.1. 标量查询(Scalar queries) 16.1.2. 实体查询(Entity queries) 16.1.3. 处理关联和集合类(Handling associations and collections) 16.1.4. 返回多个实体(Returning multiple entities) 16.1.5. 返回非...

    HibernateAPI中文版.chm

    16.1.1. 标量查询(Scalar queries) 16.1.2. 实体查询(Entity queries) 16.1.3. 处理关联和集合类(Handling associations and collections) 16.1.4. 返回多个实体(Returning multiple entities) 16.1.5. 返回非...

    Quantum Scalar i500 介绍

    Scalar® i500 是一个智能磁带库平台,可以为增长之中的中端存储环境带来更快、 更简单和更可靠的数据保护。

    Hibernate 中文 html 帮助文档

    16.1.1. 标量查询(Scalar queries) 16.1.2. 实体查询(Entity queries) 16.1.3. 处理关联和集合类(Handling associations and collections) 16.1.4. 返回多个实体(Returning multiple entities) 16.1.4.1. 别名和...

    Scalar 24 磁带库产品手册

    Quantum 的Scalar:registered: 24 对自动加载机已不能满足数据增长需要的IT 部 门具有出色的价值。Scalar 24 是一款设计小巧的双驱动器磁带库,它结合 了企业级产品的特性、性能以及低端产品的支付能力和易用性。...

    Hibernate中文详细学习文档

    16.1.1. 标量查询(Scalar queries) 16.1.2. 实体查询(Entity queries) 16.1.3. 处理关联和集合类(Handling associations and collections) 16.1.4. 返回多个实体(Returning multiple entities) 16.1.5. 返回非...

    Hibernate Reference Documentation3.1

    10.4.4. Queries in native SQL 10.5. Modifying persistent objects 10.6. Modifying detached objects 10.7. Automatic state detection 10.8. Deleting persistent objects 10.9. Replicating object between two...

    Scalar 10K磁带库产品手册

    Quantum:registered: 的Scalar:registered: 10K 是一台整合企业级备份的SAN 磁带库,能 够使IT 部门将存储整合在易于管理的单一系统中。它是业界第一台按需提 供容量磁带库,提供内置的容量扩展空间,并能使用户在...

    昆腾Scalar i6000技术研讨会

    昆腾Scalar i6000技术研讨会

    hibernate 教程

    第二层缓存(The Second Level Cache)s 14.3.1. 对映射(Mapping)缓冲 14.3.2. 策略:只读缓存 14.3.3. 策略:读/写缓存 14.3.4. 策略:不严格的读/写缓存 14.3.5. 策略:事务缓存(transactional) ...

    matlab开发-scalar2colormap

    matlab开发-scalar2colormap。灰度图像通过颜色条转换成单极或双极的RGBA图像。

    最全Hibernate 参考文档

    16. Native SQL查询 16.1. 创建一个基于SQL的Query 16.2. 别名和属性引用 16.3. 命名SQL查询 16.3.1. 使用return-property来明确地指定字段/别名 16.3.2. 使用存储过程来查询 16.3.2.1. 使用存储过程的规则和限制 ...

    Hibernate_3.2.0_符合Java习惯的关系数据库持久化

    16.1.1. 标量查询(Scalar queries) 16.1.2. 实体查询(Entity queries) 16.1.3. 处理关联和集合类(Handling associations and collections) 16.1.4. 返回多个实体(Returning multiple entities) 16.1.5. 返回非...

    Scalar_24磁带机_用户手册2010

    Scalar_24磁带机_用户手册2010。初学者了解产品必备知识手册。

    hibernate 体系结构与配置 参考文档(html)

    1. Hibernate入门 1.1. 前言 1.2. 第一部分 - 第一个Hibernate应用程序 1.2.1. 第一个class 1.2.2. 映射文件 1.2.3. Hibernate配置 1.2.4. 用Ant构建 1.2.5. 启动和辅助类 1.2.6. 加载并存储对象 1.3. 第...

    Hibernate教程

    Hibernate参考文档 目录 前言 1. 翻译说明 2. 版权声明 1. 在Tomcat中快速上手 1.1. 开始Hibernate之旅 1.2. 第一个持久化类 1.3. 映射cat 1.4. 与Cat同乐 1.5. 结语 2. Hibernate入门 2.1. 前言 2.2. 第...

    OpenCV-Python中的标量Scalar是什么.rar

    OpenCV-Python中的标量Scalar是什么.rar

    pwm.rar_SCALAR CONTROL_control_control scalar

    Scalar control for jpeg format

    scalar quantization

    该代码利用matlab对图像进行scalar quantization。程序分别对图像进行了8,16,32,64level量化,同时计算出了不同level的MSE/SNR/PSNR 。

Global site tag (gtag.js) - Google Analytics