休眠,PostgreSQL:无法提取结果集,SQLState 25P02

Posted

技术标签:

【中文标题】休眠,PostgreSQL:无法提取结果集,SQLState 25P02【英文标题】:Hibernate, PostgreSQL : Could not extract resultset, SQLState 25P02 【发布时间】:2017-03-08 09:18:08 【问题描述】:

我正在我们的一个测试服务器上工作,当我试图调用一个方法时,我从休眠中收到一个错误,在该方法中我通过其用户名获取 Person 对象。我做错了什么?

错误日志:

WARN : org.hibernate.engine.jdbc.spi.SqlExceptionHelper - SQL Error: 0, SQLState: 25P02
ERROR: org.hibernate.engine.jdbc.spi.SqlExceptionHelper - ERROR: current transaction is aborted, commands ignored until end of transaction block
WARN : org.hibernate.engine.jdbc.spi.SqlExceptionHelper - SQL Error: 0, SQLState: 25P02
ERROR: org.hibernate.engine.jdbc.spi.SqlExceptionHelper - ERROR: current transaction is aborted, commands ignored until end of transaction block
org.hibernate.exception.GenericJDBCException: could not extract ResultSet
        at org.hibernate.exception.internal.StandardSQLExceptionConverter.convert(StandardSQLExceptionConverter.java:54)
        at org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:126)
        at org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:112)
        at org.hibernate.engine.jdbc.internal.ResultSetReturnImpl.extract(ResultSetReturnImpl.java:91)
        at org.hibernate.loader.Loader.getResultSet(Loader.java:2066)
        at org.hibernate.loader.Loader.executeQueryStatement(Loader.java:1863)
        at org.hibernate.loader.Loader.executeQueryStatement(Loader.java:1839)
        at org.hibernate.loader.Loader.doQuery(Loader.java:910)
        at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:355)
        at org.hibernate.loader.Loader.doList(Loader.java:2554)
        at org.hibernate.loader.Loader.doList(Loader.java:2540)
        at org.hibernate.loader.Loader.listIgnoreQueryCache(Loader.java:2370)
        at org.hibernate.loader.Loader.list(Loader.java:2365)
        at org.hibernate.loader.hql.QueryLoader.list(QueryLoader.java:497)
        at org.hibernate.hql.internal.ast.QueryTranslatorImpl.list(QueryTranslatorImpl.java:387)
        at org.hibernate.engine.query.spi.HQLQueryPlan.performList(HQLQueryPlan.java:236)
        at org.hibernate.internal.SessionImpl.list(SessionImpl.java:1300)
        at org.hibernate.internal.QueryImpl.list(QueryImpl.java:103)
        at org.hibernate.internal.AbstractQueryImpl.uniqueResult(AbstractQueryImpl.java:966)
        at com.myproject.spring.dao.PersonDAOImpl.findPersonByUsername(PersonDAOImpl.java:118)
Caused by: org.postgresql.util.PSQLException: ERROR: current transaction is aborted, commands ignored until end of transaction block
        at org.postgresql.core.v3.QueryExecutorImpl.receiveErrorResponse(QueryExecutorImpl.java:2198)
        at org.postgresql.core.v3.QueryExecutorImpl.processResults(QueryExecutorImpl.java:1927)
        at org.postgresql.core.v3.QueryExecutorImpl.execute(QueryExecutorImpl.java:255)
        at org.postgresql.jdbc2.AbstractJdbc2Statement.execute(AbstractJdbc2Statement.java:561)
        at org.postgresql.jdbc2.AbstractJdbc2Statement.executeWithFlags(AbstractJdbc2Statement.java:419)
        at org.postgresql.jdbc2.AbstractJdbc2Statement.executeQuery(AbstractJdbc2Statement.java:304)
        at org.apache.commons.dbcp.DelegatingPreparedStatement.executeQuery(DelegatingPreparedStatement.java:96)
        at org.apache.commons.dbcp.DelegatingPreparedStatement.executeQuery(DelegatingPreparedStatement.java:96)
        at org.hibernate.engine.jdbc.internal.ResultSetReturnImpl.extract(ResultSetReturnImpl.java:82)

PersonDAOImpl :

 @Override
    @Transactional
    public Person findPersonByUsername(String username) 
        Session session = this.sessionFactory.getCurrentSession();
        Query query = session.createQuery("from Person as p where p.username=:username");
        query.setParameter("username", username);
        try 
            return (Person) query.uniqueResult();
         catch (Exception e) 
            e.printStackTrace();
            return null;
        
    

数据库在那里,我做错了什么?谢谢你。

更新这个错误总是跟在上面那个之后:

WARN : org.hibernate.engine.jdbc.spi.SqlExceptionHelper - SQL Error: 0, SQLState: 25006
ERROR: org.hibernate.engine.jdbc.spi.SqlExceptionHelper - ERROR: cannot execute nextval() in a read-only transaction
org.hibernate.exception.GenericJDBCException: could not extract ResultSet
        at org.hibernate.exception.internal.StandardSQLExceptionConverter.convert(StandardSQLExceptionConverter.java:54)
        at org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:126)
        at org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:112)
        at org.hibernate.engine.jdbc.internal.ResultSetReturnImpl.extract(ResultSetReturnImpl.java:91)
        at org.hibernate.id.SequenceGenerator.generateHolder(SequenceGenerator.java:122)
        at org.hibernate.id.SequenceHiLoGenerator$1.getNextValue(SequenceHiLoGenerator.java:81)
        at org.hibernate.id.enhanced.LegacyHiLoAlgorithmOptimizer.generate(LegacyHiLoAlgorithmOptimizer.java:77)
        at org.hibernate.id.SequenceHiLoGenerator.generate(SequenceHiLoGenerator.java:78)
        at org.hibernate.event.internal.AbstractSaveEventListener.saveWithGeneratedId(AbstractSaveEventListener.java:118)
        at org.hibernate.event.internal.DefaultSaveOrUpdateEventListener.saveWithGeneratedOrRequestedId(DefaultSaveOrUpdateEventListener.java:209)
        at org.hibernate.event.internal.DefaultSaveEventListener.saveWithGeneratedOrRequestedId(DefaultSaveEventListener.java:55)
        at org.hibernate.event.internal.DefaultSaveOrUpdateEventListener.entityIsTransient(DefaultSaveOrUpdateEventListener.java:194)
        at org.hibernate.event.internal.DefaultSaveEventListener.performSaveOrUpdate(DefaultSaveEventListener.java:49)
        at org.hibernate.event.internal.DefaultSaveOrUpdateEventListener.onSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:90)
        at org.hibernate.internal.SessionImpl.fireSave(SessionImpl.java:715)
        at org.hibernate.internal.SessionImpl.save(SessionImpl.java:707)
        at org.hibernate.internal.SessionImpl.save(SessionImpl.java:702)

【问题讨论】:

尝试添加@Transactional(propagation="REQUIRES_NEW") 并检查它可能由于任何其他尚未回滚的事务而失败 @rathna :没有帮助,同样的错误。 catch (Exception e) e.printStackTrace(); return null; 确实是一种不好的做法。您的方法看起来不错,但是 earlier 异常导致当前事务失败。但是失败的事务需要回滚(至少到某个“干净”的保存点)。 -- 永远不要处理这样的异常,尤其是在涉及事务时。您至少可以将它们重新扔给RuntimeExceptions,例如catch (Exception e) throw new RuntimeException(e); 您确定您选择了正确的架构/表组合吗?您可以检查 Postgresql 日志。他们应该披露有关异常原因的更多信息。 @pozs :我为所有返回来自数据库的单个对象的方法添加了空检查。这还不够吗? 【参考方案1】:

您的实际问题很简单:您在只读事务中调用了save() 操作。

但是,因为你吞下了你的例外:

 catch (Exception e) 
    e.printStackTrace();
    return null;

你不能轻易调试。中止的异常需要回滚(至少到一个保存点,它在创建时没有中止)。

当一个事务处于这种“中止”状态时,任何后续查询都会抛出这个当前事务被中止,命令被忽略直到事务块结束异常。

您应该(至少)重新抛出异常以避免将来出现这种情况:

 catch (Exception cause) 
    // print or log the error here, before re-throwing
    throw new RuntimeException(cause);

有了这个,你会首先得到正确的错误。

【讨论】:

以上是关于休眠,PostgreSQL:无法提取结果集,SQLState 25P02的主要内容,如果未能解决你的问题,请参考以下文章

jpa(休眠)中具有重复行的结果集

PostgreSQL查询结果集去掉返回行数

PostgreSQl 函数返回多个动态结果集

Spring DATA JPA 传递两个参数 - 无法提取 ResultSet;SQL [n/a]; org.hibernate.exception.SQLGrammerException:无法提取结

将时间戳与查询中的日期名称相等,并在 PostgreSQL 查询中获取结果集 w.r.t 日期名称

使用可滚动结果集在休眠中批量读取数据