Could not extract ResultSet When i using Native Query in Spring Jpa - java

I am trying to get true or false, with some compare condition using Spring JPA native query. But I got following Exception,
could not extract ResultSet; SQL [n/a]; nested exception is org.hibernate.exception.SQLGrammarException: could not extract ResultSet
The query I am trying is:
SELECT case when ABS(am_savedagent.AGENT_VERSION)< 1.8 then 'true' else 'false' end as bool
FROM am_savedagent where am_savedagent.BOX_ID="ots-JIO6Yn0jZbxs";
My Repository
public interface SavedAgentRepository extends JpaRepository<SavedAgentDetails, String>, JpaSpecificationExecutor<SavedAgentDetails> {
#Query(value = "SELECT case when ABS(SavedAgentDetails.agentVersion)< ?1 then 'true' else 'false' end as bool FROM SavedAgentDetails where SavedAgentDetails.boxId=?2", nativeQuery = true)
public Optional<List<Object>> findByAgentVersionAndBoxId(String currentVersion, String boxid);
}
I can't find y the Errors Comming. please help me, someone.

Since you are using native query =true,
that's why you need to use the table name and not the entity name inside your query.
Try this -->
public interface RegisterAgentRepository extends JpaRepository<RegisterAgentDetails, String>, JpaSpecificationExecutor<RegisterAgentDetails> {
#Query(value = "SELECT case when ABS(am_registeragent.AGENT_VERSION)< ?1 then 'true' else 'false' end as bool FROM am_registeragent where am_registeragent.SAASBOX_ID=?2", nativeQuery = true)
public Optional<List<Object>> findByAgentVersionAndSaasboxId(String currentVersion, String saasboxid);
}

Related

Spring Data JDBC #Modifying with PostgreSQL RETURNING to return data from modified rows

PostgreSQL provides a neat way to return data from DML statements, see https://www.postgresql.org/docs/current/dml-returning.html
What I tried to achieve is something like the following snipped
#Modifying
#Query("DELETE FROM Book b WHERE b.title = :title RETURNING *")
Book deleteReturning(#Param("title") String title);
to retrieve the deleted row.
However, this leads to the following exception
org.springframework.dao.DataIntegrityViolationException: PreparedStatementCallback; SQL [DELETE FROM Book b WHERE b.title = ? RETURNING *]; A result was returned when none was expected.; nested exception is org.postgresql.util.PSQLException: A result was returned when none was expected.
at org.springframework.jdbc.support.SQLStateSQLExceptionTranslator.doTranslate(SQLStateSQLExceptionTranslator.java:104)
at org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:72)
at org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:81)
at org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:81)
at org.springframework.jdbc.core.JdbcTemplate.translateException(JdbcTemplate.java:1443)
at org.springframework.jdbc.core.JdbcTemplate.execute(JdbcTemplate.java:633)
at org.springframework.jdbc.core.JdbcTemplate.update(JdbcTemplate.java:862)
at org.springframework.jdbc.core.JdbcTemplate.update(JdbcTemplate.java:883)
at org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate.update(NamedParameterJdbcTemplate.java:321)
at org.springframework.data.jdbc.repository.query.AbstractJdbcQuery.lambda$createModifyingQueryExecutor$0(AbstractJdbcQuery.java:103)
at org.springframework.data.jdbc.repository.query.StringBasedJdbcQuery.execute(StringBasedJdbcQuery.java:85)
at org.springframework.data.repository.core.support.QueryExecutorMethodInterceptor$QueryMethodInvoker.invoke(QueryExecutorMethodInterceptor.java:195)
at org.springframework.data.repository.core.support.QueryExecutorMethodInterceptor.doInvoke(QueryExecutorMethodInterceptor.java:152)
at org.springframework.data.repository.core.support.QueryExecutorMethodInterceptor.invoke(QueryExecutorMethodInterceptor.java:130)
...
Caused by: org.postgresql.util.PSQLException: A result was returned when none was expected.
at org.postgresql.jdbc.PgStatement.checkNoResultUpdate(PgStatement.java:269)
at org.postgresql.jdbc.PgPreparedStatement.executeUpdate(PgPreparedStatement.java:131)
at com.zaxxer.hikari.pool.ProxyPreparedStatement.executeUpdate(ProxyPreparedStatement.java:61)
at com.zaxxer.hikari.pool.HikariProxyPreparedStatement.executeUpdate(HikariProxyPreparedStatement.java)
at org.springframework.jdbc.core.JdbcTemplate.lambda$update$0(JdbcTemplate.java:867)
at org.springframework.jdbc.core.JdbcTemplate.execute(JdbcTemplate.java:617)
... 95 more
Spring Data JDBC states that a modifying query can return void, int and boolean only, see
https://docs.spring.io/spring-data/jdbc/docs/current/reference/html/#jdbc.query-methods.at-query.modifying
Adding a custom RowMapper leads to the same exception.
public class BookRowMapper<T> implements RowMapper<Book> {
#Override
public Book mapRow(final ResultSet rs, final int rowNum) throws SQLException {
return new Book(rs.getString(1), ...);
}
}
#Modifying
#Query(value = "delete from Book b where b.title = :title returning *", rowMapperClass = BookRowMapper.class)
Book deleteReturning(#Param("title") String title);
Is there an option to achieve this?
Edit: I am aware of plain JDBC https://stackoverflow.com/a/40787385/1239904 but I would like to go with the Spring way.
When you annotate the method with #Modifying it is executed it is executed as a DML statement which does not return any value except the number of rows updated.
If your statement returns a ResultSet you should not use #Modifying, so Spring Data JDBC tries to extract the ResultSet and create return values for the method from it.

Creating query exception in JPA while creting custom query method

JPA repository throwing Error for custom query method:
org.h2.jdbc.JdbcSQLException: Table "NBMRBANKDTLSENTITY" not found; SQL statement:
select NBMRBankDtlsEntity from NBMRBankDtlsEntity where NBMRBankDtlsEntity.ipphId = ? [42102-191]
at org.h2.message.DbException.getJdbcSQLException(DbException.java:345)
Class :
#Repository
public interface NBMRBankDtlsRepository extends JpaRepository<NBMRBankDtlsEntity, Long> {
#Query(value ="select n from NBMRBankDtlsEntity n where n.ipphId = :ipphId",nativeQuery = true)
Optional<NBMRBankDtlsEntity> findByIPPHId(#Param("ipphId") Long ipphId);
}
The error message tells you: Table "NBMRBANKDTLSENTITY" not found. Therefore it probably doesn't exist. To fix this you'll have to create the table, manually through a script or through hibernates schema creation feature.
I am already creating a table also inserting the record, After that only i am calling this custom query method.
I have found the issue as i am using nativeQuery = true so it is expecting normal sql query to query DB directly not the java query which is creating issue. Now after changing below it works fine ,
#Query(value = "SELECT * from NB_MR_BANK_DTLS WHERE IPPH_ID = :ipphId",nativeQuery = true)
For java query we can use directly as it internally converts to SQL while querying the DB,
#Query(value = "select p from NBMRBankDtlsEntity p WHERE p.ipphId = :ipphId")

SQLGrammarException: could not execute statement while trying to delete from db

I'm trying to solve a problem with statement deletion query. Now the implementation looks like this.
#Transactional
public void deleteStatements(LocalDate expiryDate) {
int deletedStatements = statementRepository.deleteByIdCreatedDateBefore(expiryDate);
logger.info("Deleted {} statements.", deletedStatements);
}
#Query(value = "WITH deleted AS (DELETE FROM generated_statements WHERE created_date < :expiryDate RETURNING id) " +
"SELECT count(*) FROM deleted;", nativeQuery = true)
int deleteByIdCreatedDateBefore(LocalDate expiryDate);
Now I'm getting this error:
could not execute statement; SQL [n/a]; nested exception is org.hibernate.exception.SQLGrammarException: could not execute statement
I tried adding #Modifying annotation, then I tried removing it, tried with various combinations of #Transactional and #Modifying, still got various errors regarding this deletion like:
could not extract ResultSet; SQL [n/a]; nested exception is org.hibernate.exception.SQLGrammarException: could not extract ResultSet or Executing an update/delete query; nested exception is javax.persistence.TransactionRequiredException: Executing an update/delete query
Now I'm really not sure what is the problem here.
Replace your delete query with this
#Modifying
#Query(value = "DELETE FROM generated_statements WHERE created_date < :expiryDate", nativeQuery = true)
int deleteByIdCreatedDateBefore(LocalDate expiryDate);
or turn it directly into a JPQL/HQL query. No need for a nativeQuery. Example:
#Modifying
#Query(value = "DELETE FROM GeneratedStatement g WHERE g.createDate < :expiryDate")
int deleteByIdCreatedDateBefore(LocalDate expiryDate);
By specifying an int return value, you will automatically get the number of deleted rows.
Considering all this complex logic is to get number of deleted rows you can try just:
#Modifying
#Query("DELETE FROM generated_statements WHERE created_date < :expiryDate")
int deleteByIdCreatedDateBefore(LocalDate expiryDate);
or just using keywords(if your entity has createdDate attribute)
int deleteByCreatedDateBefore(LocalDate expiryDate);
#Modifying
#Query(value = "DELETE FROM generated_statements WHERE created_date < ?1", nativeQuery = true)
int deleteByIdCreatedDateBefore(LocalDate expiryDate);

org.postgresql.util.PSQLException: No results were returned by the query [duplicate]

I am trying to insert a data into a table. After executing the query i am getting an exception stating
org.postgresql.util.PSQLException: No results were returned by the query.
org.postgresql.jdbc2.AbstractJdbc2Statement.executeQuery(AbstractJdbc2Statement.java:284)
The data is getting inserted successfully, but i have no idea why i am getting this exception ??
Use
executeUpdate
instead of
executeQuery
if no data will be returned (i.e. a non-SELECT operation).
Please use #Modifying annotation over the #Query annotation.
#Modifying
#Query(value = "UPDATE Users set coins_balance = coins_balance + :coinsToAddOrRemove where user_id = :user_id", nativeQuery = true)
int updateCoinsBalance(#Param("user_id") Long userId, #Param("coinsToAddOrRemove") Integer coinsToAddOrRemove);
The same is true for any DML query (i.e. DELETE, UPDATE or INSERT)
Using #Modifying and #Transaction fixed me
The problem that brought me to this question was a bit different - I was getting this error when deleting rows using an interface-based Spring JPA Repository. The cause was that my method signature was supposed to return some results:
#Modifying
#Query(value = "DELETE FROM table t WHERE t.some_id IN (:someIds)", nativeQuery = true)
List<Long> deleteBySomeIdIn(#Param("someIds") Collection<Long> someIds);
Changing the return type to void resolved the issue:
#Modifying
#Query(value = "DELETE FROM table t WHERE t.some_id IN (:someIds)", nativeQuery = true)
void deleteBySomeIdIn(#Param("someIds") Collection<Long> someIds);
If you want last generated id, you can use this code after using executeUpdate() method
int update = statement.executeUpdate()
ResultSet rs = statement.getGeneratedKeys();
if (rs != null && rs.next()) {
key = rs.getLong(1);
}
I have solved this Problem using addBatch and executeBatch as following:
statement.addBatch("DELETE FROM public.session_event WHERE id = " + entry.getKey());
statement.executeBatch();

Spring hibernate : Could not extract result set metadata

I try to use a native query in my Dao (extended from JpaRepository), but i get this exception :
org.springframework.orm.jpa.JpaSystemException: Could not extract result set metadata; nested exception is org.hibernate.HibernateException: Could not extract result set metadata
Here is my native query:
#Repository
public interface BenchDao extends JpaRepository<Bench, Long> {
#Query(nativeQuery=true,value="UPDATE TF_BENCH SET ISDELETED = 1, SEQ = (select CASE WHEN (min(BENCH.SEQ) < 1) THEN (min(BENCH.SEQ)-1) ELSE -1 END from TF_BENCH BENCH WHERE BENCH.STAGE = (select BENCH.STAGE from TF_BENCH BENCH WHERE id =29302)) WHERE id =29302")
void deleteBench();
When i try this request on Oracle SQL developper it works, but through spring and hibernate it doesn't.
In the stack trace exeception I have also this message :
Caused by: java.sql.SQLSyntaxErrorException: ORA-00900: invalid SQL statement
I've tried to google exception messages, but I found nothing...
I think that a better solution was to add the #Modifying annotation to your method.
See more on the following Answer : Spring Data JPA delete native query throwing exception
I've found a solution : if someone need :
#Repository
public class BenchDaoCustomImpl implements BenchDaoCustom {
#PersistenceContext
private EntityManager em;
public void deleteBench(Long benchId) {
this.em.createNativeQuery("UPDATE TF_BENCH SET ISDELETED = 1, SEQ = (select CASE WHEN (min(BENCH.SEQ) < 1) THEN (min(BENCH.SEQ)-1) ELSE -1 END from TF_BENCH BENCH WHERE BENCH.STAGE = (select BENCH.STAGE from TF_BENCH BENCH WHERE id =?0)) WHERE id =?0")
.setParameter(0, benchId)
.executeUpdate();
}
}

Categories