hibernate存储过程查询缓存

时间:2013-07-22 15:55:52

标签: hibernate hibernate-mapping ehcache hibernate-cache

我们正在使用hibernate将存储过程结果映射到java对象。 它使用hibernate 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查询而不是存储过程调用。

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

提前感谢您的帮助。

1 个答案:

答案 0 :(得分:0)

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

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

为酒店类添加以下注释修复了该问题 @Loader(namedQuery =“fetchHotel”)