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);
Related
While writing a pagination query in repository as below code segment, I'm getting following error.
Code
#Repository
public interface Aaaa extends PagingAndSortingRepository<TxnDealerInventoryItem, Long> {
#Query(value = "SELECT EM.PART_NO, EM.PART_NAME FROM TXN_DEALER_INVENTORY_ITEM E INNER JOIN MST_PRODUCT EM ON E.PRODUCT_ID = EM.PRODUCT_ID WHERE E.ACCOUNT_ID= :accountId AND EM.ALLOW_SERIAL_NUM = :isSerialized ORDER BY ?#{#pageable}",
countQuery = "SELECT COUNT(*) FROM TXN_DEALER_INVENTORY_ITEM E INNER JOIN MST_PRODUCT EM ON E.PRODUCT_ID = EM.PRODUCT_ID WHERE E.ACCOUNT_ID= :accountId AND EM.ALLOW_SERIAL_NUM = :isSerialized",
nativeQuery = true)
Page<Object[]> getNonSerializedDeviceList(#Param("accountId") Long accountId, #Param("isSerialized") String isSerialized, Pageable pageable);
}
Error
HQL: SELECT COUNT(*) FROM TXN_DEALER_INVENTORY_ITEM E INNER JOIN MST_PRODUCT EM ON E.PRODUCT_ID = EM.PRODUCT_ID WHERE E.ACCOUNT_ID= :accountId AND EM.ALLOW_SERIAL_NUM = :isSerialized
2023-02-10 18:52:52,753 ERROR [org.hibernate.hql.internal.ast.ErrorCounter] (http-/127.0.0.1:8881-1) line 1:76: unexpected token: ON
Native Query doesn't have any error when run from sql developer.
Framework versions are as follows, Unfortunately I'cant update these any further as there are limitations in deployment environment. You inputs are highly welcome on this !!
<spring.version>4.3.30.RELEASE</spring.version>
<spring.data.version>1.11.23.RELEASE</spring.data.version>
<hibernate.version>4.2.18.Final</hibernate.version>
PS : for testing purpose when I change the SQL to a very basic like a select *, It gives following error.
org.hibernate.hql.internal.ast.QuerySyntaxException: TXN_DEALER_INVENTORY_ITEM is not mapped [SELECT COUNT(*) FROM TXN_DEALER_INVENTORY_ITEM E ]
Got the problem resolved by removing the count query and make the return type to a List of object Array instead of Page as below code segment.
#Repository
public interface Aaaa extends PagingAndSortingRepository<TxnDealerInventoryItem, Long> {
#Query(value = "SELECT EM.PART_NO, EM.PART_NAME FROM TXN_DEALER_INVENTORY_ITEM E INNER JOIN MST_PRODUCT EM ON E.PRODUCT_ID = EM.PRODUCT_ID WHERE E.ACCOUNT_ID= :accountId AND EM.ALLOW_SERIAL_NUM = :isSerialized ORDER BY ?#{#pageable}",
nativeQuery = true)
List<Object[]> getNonSerializedDeviceList(#Param("accountId") Long accountId, #Param("isSerialized") String isSerialized, Pageable pageable);
}
Finally having good old Paginations :) Thanks everyone who looked into this.
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);
}
I'm using JPARepository in SpringBoot and using the #Query annotation but I get an error
org.springframework.dao.InvalidDataAccessResourceUsageException: could not extract ResultSet; SQL [n/a]; nested exception is org.hibernate.exception.SQLGrammarException: could not extract ResultSet
When using the nativeQuery=true
This is my function:
#Query(value = "select * from table1 where status = ?1 and time <= ?2 LIMIT 2", nativeQuery = true)
List<MyModel> findScheduledSmsMessages(Status status, LocalDateTime time);
I added the following code above my query and
#Modifying
#Transactional
Like this :
#Modifying
#Transactional
#Query(value = "DELETE FROM played_sheet WHERE user_id = ?1 AND sheet_music_id = ?2", nativeQuery = true)
void deleteByUserIdAndSheetMusicId(Integer userId,Integer sheetMusicId);
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 keep getting errors when trying to get this SQL correct for a JPA repository delete. What is the correct syntax?
#Query("delete * from TS t inner join TSC c ON t.tenantId = c.id where t.id= ?1 AND c.endDate < ?2")
void deleteTSWithExpiredDate(Long id, Date date);
Caused by: java.lang.IllegalArgumentException: node to traverse cannot be null!
at org.hibernate.hql.internal.ast.util.NodeTraverser.traverseDepthFirst(NodeTraverser.java:63)
Another
#Query("delete t.* from TS t inner join TSC c ON t.tenantId = c.id where t.id= ?1 AND c.endDate < ?2")
void deleteTSWithExpiredDate(Long id, Date date);
expecting IDENT, found '*' near line 1, column 10 [delete t.*
Another
#Query("delete t from TS t inner join TSC c ON t.tenantId = c.id where t.id= ?1 AND c.endDate < ?2")
void deleteTSWithExpiredDate(Long id, Date date);
unexpected token: from near line 1, column 10 [delete t
The syntax for bulk delete is:
Query q = session.createQuery("delete Entity where id = :idParam");
// set params here
q.executeUpdate();
However from Hibernate documentation, no joins can be specified in a bulk HQL query. Sub-queries can be used in the where-clause, where the sub-queries themselves can contain joins.