Hibernate 5:使用命名查询和无状态会话返回 java.lang.UnsupportedOperationException

Posted

技术标签:

【中文标题】Hibernate 5:使用命名查询和无状态会话返回 java.lang.UnsupportedOperationException【英文标题】:Hibernate 5: using named query with stateless session returning java.lang.UnsupportedOperationException 【发布时间】:2020-09-11 13:08:43 【问题描述】:

在我们将项目从 hibernate 4 升级到 5 后,我们遇到了这个异常,我们试图从无状态会话的命名查询中获取可滚动的结果。到目前为止,我们已经尝试对其进行谷歌搜索并设置参数,但似乎在 NamedQuery 对象中默认启用了缓存,并且当尝试在其中设置 chacheMode 时,无状态会话类抛出 java.lang.UnsupportedOperationException(hibernate 自己的实现)。以下是代码:

public <T> Results<T> fetchScrollableResultsByQueryName(String queryName, List<String> paramNames, List<Object> paramValues)
        StatelessSession slsession  = getStatelessSession();
        ScrollableResults scrollableResults = createQueryByName(queryName, slsession, paramNames,  paramValues).scroll(ScrollMode.FORWARD_ONLY);
        return(new ResultsHibernateStateless<T>(scrollableResults, slsession));
    

protected Query createQuery(String queryStr, StatelessSession slsession, List<String> paramNames, List<Object> paramValues ) 
        Query query = (Query) slsession.createQuery(queryStr);
        setQueryTimeout(query);
        query.setFetchSize(fetchSize);
        query.setReadOnly(true);
        query.setCacheMode(null);
        query.setCacheable(false);
        this.addNamedParamToQuery(query, paramNames,  paramValues);
        return query;
    

这是异常的堆栈跟踪

2020-09-11 10:04:18,922 ERROR uk.ac.ebi.ppmc.business.service.bookindexer.BookPPMCService/processBooks 202 - 
java.lang.UnsupportedOperationException
    at org.hibernate.internal.StatelessSessionImpl.setCacheMode(StatelessSessionImpl.java:457)
    at org.hibernate.query.internal.AbstractProducedQuery.beforeQuery(AbstractProducedQuery.java:1437)
    at org.hibernate.query.internal.AbstractProducedQuery.scroll(AbstractProducedQuery.java:1485)
    at org.hibernate.query.internal.AbstractProducedQuery.scroll(AbstractProducedQuery.java:110)
    at uk.ac.ebi.literature.db.dao.impl.CrudDAOImpl.fetchScrollableResultsByQueryName(CrudDAOImpl.java:505)
    at uk.ac.ebi.ppmc.business.service.bookindexer.BookLoaderService.loadBookInfo(BookLoaderService.java:114)
    at uk.ac.ebi.ppmc.business.service.bookindexer.BookPPMCService.processBooks(BookPPMCService.java:176)
    at uk.ac.ebi.ppmc.business.service.bookindexer.BookPPMCService.main(BookPPMCService.java:95)

如果有人可以判断这是否是 hibernate 5 中的一个已知错误,或者是否有解决此问题的方法??

【问题讨论】:

我们也在hibernate社区hibernate.atlassian.net/browse/HHH-12012上发现了这个问题,但不确定他们是否承认或提供任何解决方案, 【参考方案1】:

我认为你的问题的根本原因在这一行:

query.setCacheMode(null);

您应该直接删除它,因为如果您查看implementation,您会看到:

@Override
public void setCacheMode(CacheMode cm) 
    throw new UnsupportedOperationException();

另请参阅documentation 中的其他信息:

StatelessSession 未提供的一些内容包括:

一级缓存 与任何二级缓存或查询缓存的交互 事务性后写或自动脏检查

【讨论】:

好吧,我都试过了,设置不同的值加上完全删除这一行,问题是cacheMode在此之前被预初始化 那么,删除此行后您会看到什么异常。 同样的异常。 能否请您提供此代码中提到的所有 sn-p 方法的完整实现,例如:getStatelessSessionsetQueryTimeoutaddNamedParamToQuery。或在 github 上发布允许重现此问题的最小项目。 我已经附上了这个报告的休眠问题[链接]hibernate.atlassian.net/browse/HHH-12012。您可以尝试运行此问题中提到的测试用例,并会看到异常。【参考方案2】:

尝试在调用 .scroll(ScrollMode.FORWARD_ONLY) 之前设置提示:

query.setHint(JPA_SHARED_CACHE_STORE_MODE, null); query.setHint(JPA_SHARED_CACHE_RETRIEVE_MODE, null);

【讨论】:

以上是关于Hibernate 5:使用命名查询和无状态会话返回 java.lang.UnsupportedOperationException的主要内容,如果未能解决你的问题,请参考以下文章

有状态bean和无状态的bean

使用 Hibernate 5.2 以流形式查询结果

Hibernate命名查询

改进的命名策略不再在 Hibernate 5 中工作

org.hibernate.MappingException 命名查询未知

(N)Hibernate“每个应用程序会话”被认为是特定用例的邪恶?