2017-03-08 1 views
2

Je travaille sur l'un de nos serveurs de test et je reçois une erreur de la mise en veille prolongée lorsque j'essaie d'appeler une méthode, où j'obtiens l'objet Person par son nom d'utilisateur. Qu'est-ce que je fais mal?Hibernate, PostgreSQL: impossible d'extraire le resultset, SQLState 25P02

journal d'erreur:

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; 
     } 
    } 

La base de données est là, qu'est-ce que je fais mal? Je vous remercie.

Mise à jour Cette erreur suit toujours ce qui précède celui-ci:

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) 
+0

Essayez d'ajouter @Transactional (propagation = "REQUIRES_NEW") et vérifiez qu'il peut échouer en raison de toute autre transaction qui n'a pas été annulée – rathna

+0

@rathna: DId pas d'aide, même erreur. –

+0

'catch (Exception e) {e.printStackTrace(); return null; } 'est vraiment une mauvaise pratique. Votre méthode semble correcte, mais une exception ** plus tôt ** a provoqué l'échec de la transaction en cours. Mais les transactions échouées doivent être annulées (au moins jusqu'à un certain point de sauvegarde, qui était "propre"). - Ne gérez jamais les exceptions de ce type, en particulier lorsque des transactions sont impliquées. Le moins que vous puissiez faire est de leur renvoyer une 'RuntimeException's, comme' catch (Exception e) {throw new RuntimeException (e); } ' – pozs

Répondre

1

Votre problème réel est simple: vous avez appelé une opération save() dans une transaction en lecture seule.

Mais, parce que vous avalez vos exceptions avec:

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

vous ne pouvez pas déboguer facilement. Les exceptions abandonnées doivent être annulées (au moins pour un point de sauvegarde, qui n'a pas été abandonné au moment de sa création). Lorsqu'une transaction reste dans cet état "abandonné", toute requête suivante lancera cette transaction en cours, les commandes seront ignorées jusqu'à la fin du bloc de transaction.

Vous devriez (au moins) des exceptions re lancers francs pour éviter des cas comme celui-ci à l'avenir:

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

Avec cela, vous obtiendrez l'erreur correcte à la première place.