hibernate存储过程查询缓存

hibernate存储过程查询缓存,hibernate,hibernate-mapping,ehcache,hibernate-cache,Hibernate,Hibernate Mapping,Ehcache,Hibernate Cache,我们使用hibernate将存储过程结果映射到java对象。 它使用Hibernate4.1.x在SQLServer2008上执行 @XmlRootElement(name = "hotel") @Entity @NamedNativeQuery(name = "fetchHotel", query = "{ call usp_iconnect_dashboard_gethotels(:screenname) }", resultSetMapping = "hotel-data", hints

我们使用hibernate将存储过程结果映射到java对象。 它使用Hibernate4.1.x在SQLServer2008上执行

@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>
和上面的日志一样,它会在一段时间后尝试以SELECT查询而不是存储过程调用的形式获取

知道为什么会这样吗? 因此,查询缓存不能用于在hibernate中缓存存储过程。 对于存储过程结果,是否有其他方法使用缓存?


提前感谢您的帮助。

这里描述的问题似乎与此类似

解决方案是使用文档中描述的@Loader

为Hotel class添加以下注释修复了该问题 @加载器(namedQuery=“fetchHotel”)

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'.