0

我们正在使用休眠将存储过程结果映射到 java 对象。它使用休眠 4.1.x 在 SQL Server 2008 上执行

@XmlRootElement(name = "hotel")
@Entity
@NamedNativeQuery(name = "fetchHotel",
query = "{ call usp_iconnect_dashboard_gethotels(:screenname) }",
resultSetMapping = "hotel-data",
hints = {@QueryHint(name = "org.hibernate.callable", value = "true") }
)
@SqlResultSetMapping(name = "hotel-data",
entities = @EntityResult(entityClass = Hotel.class))
@Cache(usage = CacheConcurrencyStrategy.READ_ONLY)
public class Hotel {

    /**
     * Unique hotel code.
     */
    @Id
    @Column(name = "hotelcode")
    private String code;

    /**
     * Hotel name.
     */
    @Column(name = "hotel")
    private String name;

    /**
     * Indicates if user belongs to hotel.
     * Y - if it is default hotel.
     * N - if it is not default hotel.
     */
    @Column(name = "is_default")
    private String isDefault;

    /**
     * @return the code
     */
    public final String getCode() {
        return code;
    }

    /**
     * @param code the code to set
     */
    public final void setCode(final String code) {
        this.code = code;
    }

    /**
     * @return the name
     */
    public final String getName() {
        return name;
    }

    /**
     * @param name the name to set
     */
    public final void setName(final String name) {
        this.name = name;
    }

    /**
     * @return the isDefault
     */
    public final String getIsDefault() {
        return isDefault;
    }

    /**
     * @param isDefault the isDefault to set
     */
    public final void setIsDefault(final String isDefault) {
        this.isDefault = isDefault;
    }

}

它可以很好地获取结果。

但是,当启用二级缓存 (ehcache) 和查询缓存时。

<property name="hibernateProperties">
    <props>
    <prop key="hibernate.dialect">${dialect}</prop>
            <prop key="hibernate.show_sql">${showSQL}</prop>
            <prop key="format_sql">true</prop>
            <prop key="hibernate.current_session_context_class">thread</prop>
            <prop key="hibernate.connection.release_mode">on_close</prop>
            <prop key="hibernate.transaction.factory_class">org.hibernate.transaction.JDBCTransactionFactory</prop>
            <prop key="hibernate.cache.provider_class">org.hibernate.cache.EhCacheProvider</prop>
            <prop key="hibernate.cache.region.factory_class">org.hibernate.cache.ehcache.EhCacheRegionFactory</prop>
            <prop key="hibernate.cache.use_second_level_cache">true</prop>
            <prop key="hibernate.cache.use_query_cache">true</prop>
        </props>
    </property>

添加查询缓存可以正常工作。然而,经过几次通话,它给出的错误如下。

DEBUG StandardQueryCache - Checking cached query results in region: DailyExpire
DEBUG EhcacheGeneralDataRegion - key: sql: { call usp_iconnect_dashboard_gethotels(?) }; parameters: ; named parameters: {screenname=dhulipah}; transformer: org.hibernate.transform.CacheableResultTransformer@110f2
DEBUG StandardQueryCache - Checking query spaces are up-to-date: [Hotel]
DEBUG EhcacheGeneralDataRegion - key: Hotel
DEBUG EhcacheGeneralDataRegion - Element for key Hotel is null
DEBUG StandardQueryCache - Returning cached query results
Hibernate: select hotel0_.hotelcode as hotelcod1_1_0_, hotel0_.is_default as is2_1_0_, hotel0_.hotel as hotel3_1_0_ from Hotel hotel0_ where hotel0_.hotelcode=?
WARN  SqlExceptionHelper - SQL Error: 208, SQLState: S0002
ERROR SqlExceptionHelper - Invalid object name 'Hotel'.
INFO  DefaultLoadEventListener - HHH000327: Error performing load command : org.hibernate.exception.SQLGrammarException: Invalid object name 'Hotel'.
Jul 22, 2013 3:25:39 PM com.sun.jersey.spi.container.ContainerResponse mapMappableContainerException
SEVERE: The RuntimeException could not be mapped to a response, re-throwing to the HTTP container
org.hibernate.exception.SQLGrammarException: Invalid object name 'Hotel'.

与上面的日志一样,它试图在一段时间后作为 SELECT 查询而不是存储过程调用来获取。

知道为什么会这样吗?因此,查询缓存不能用于在休眠中缓存存储过程。有没有其他方法可以为存储过程结果使用缓存?

提前感谢您的帮助。

4

1 回答 1

0

它似乎与此处描述的类似问题 https://hibernate.atlassian.net/browse/HHH-610

解决方案是按照文档 http://docs.jboss.org/hibernate/orm/4.1/devguide/en-US/html_single/#querysql-load中的描述使用@Loader

为 Hotel 类添加以下注释修复了问题 @Loader(namedQuery = "fetchHotel")

于 2013-07-23T11:52:28.290 回答