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
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.
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")
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);
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();
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();
}
}