Spring JPA Hibernate giving error updating timestamp wo timezone in postgres - postgresql

I have been trying to update timestamp field using an update stmt. I tried java.sql.timestamp, java.util.date, Calendar, LocalDateTime, ZonedDateTime and bunch of other java date util packages. None of them seem to be working.
Column: commit_ts (TimeStamp without Timezone in Postgresql) is defined in our JPA/Hibernate as
#Column(name = "COMMIT_TS")
#Temporal(TemporalType.TIMESTAMP)
private Timestamp commitTs;
here is the Query
#Timed(name = "updateWorkAllocationStatus")
#Transactional
#Modifying(clearAutomatically = true)
#Query(
nativeQuery = true,
value = "UPDATE wlm_work_allocation SET commit_ts=:ts " +
"WHERE allocation_id = :allocationId " +
"and status = :status " +
"and commit_ts == null"
)
int updateWorkAllocationStatus(
#Param("timestamp") Timestamp ts,
#Param("allocationId")Long allocationId,
#Param("status")String status
);
I also tried NativeQueries
#NamedNativeQuery(name = "WorkAllocationEntity.updateCommitTs",
query="UPDATE wlm_work_allocation SET commit_ts= TIMESTAMP WHERE allocation_id=:allocationId and status=:status and commit_ts==null")
Note: According to this link,The SQL standard requires that writing just timestamp be equivalent to timestamp without time zone, and PostgreSQL honors that behavior.
https://www.postgresql.org/docs/9.1/static/datatype-datetime.html
Springboot version :1.5.7.RELEASE
Postgres JDBC Driver : 9.0-801.jdbc4
PostgresSQL DB: 9.6.5
Error:
org.postgresql.util.PSQLException: ERROR: operator does not
exist: timestamp without time zone == unknown
Hint: No operator matches the given name and argument type(s).
You might need to add explicit type casts.
Can anyone help?

The comparison operator in JPQL and SQL is = not ==
commit_ts==null
should be
commit_ts is null

Related

JPA Criteria on PostgreSQL boolean type creates invalid query

I have a regular JPA Entity which has a boolean field:
#Entity("UserAccount")
public class UserAccount {
...
#Column(name = "isActive")
private boolean isActive = false;
...
}
This is backed by a table in PostgreSQL 15. In the table definition, the field is of type BOOLEAN (not integer!):
CREATE TABLE UserAccount(
...
isActive BOOLEAN NOT NULL,
...
)
When I attempt to use the JPA Criteria API with it:
criteriaBuilder.isTrue(root.get("isActive"))
... then it will be rendered as = 1 in the SQL query which is sent to PostgreSQL:
SELECT ...
FROM UserAccount
WHERE isActive = 1
PostgreSQL rejects this query with the following error (which is pretty clear):
PSQLException: ERROR: operator does not exist: boolean = integer
Hint: No operator matches the given name and argument types. You might need to add explicit type casts.
My question is: how can I tell Hibernate that I'm using an actual PostgreSQL-native BOOLEAN type in my table instead of encoding the boolean as a number?

Error while ignoring null query parameters - Spring JPA

I am using Spring JPA in my application to fetch certain records from the DB. Now, one of the query parameters that I am passing can be null in certain criteria. So I have designed the query in such a way that if the query parameter is not null, then the query parameter is used for extraction otherwise it is ignored.
Query
#Query(value = "SELECT * FROM fulfilment_acknowledgement WHERE entity_id = :entityId " +
"and item_id = :itemId " +
"and (fulfilment_id is null OR :fulfilmentId is null OR fulfilment_id = :fulfilmentId) " +
"and type = :type", nativeQuery = true)
FulfilmentAcknowledgement findFulfilmentAcknowledgement(#Param(value = "entityId") String entityId, #Param(value = "itemId") String itemId,
#Param(value = "fulfilmentId") Long fulfilmentId, #Param(value = "type") String type);
NOTE: The type of fulfilment_id in the table fulfilment_acknowledgement is int8. It is a Postgres RDS.
Now, if I encounter a scenario where the fulfilmentId is actually blank, I am getting the below error:
2022-06-23 15:31:56,997 89645 [boundedElastic-5] DEBUG org.hibernate.SQL - SELECT * FROM fulfilment_acknowledgement WHERE entity_id = ? and item_id = ? and (fulfilment_id is null OR ? is null OR fulfilment_id = ?) and type = ?
2022-06-23 15:31:57,154 89802 [boundedElastic-5] DEBUG o.h.e.jdbc.spi.SqlExceptionHelper - could not extract ResultSet [n/a]
Exception while creating Fulfilment Acknowledgement: [could not extract ResultSet; SQL [n/a]; nested exception is org.hibernate.exception.SQLGrammarException: could not extract ResultSet]
Caused by: org.hibernate.exception.SQLGrammarException: could not extract ResultSet
Caused by: org.postgresql.util.PSQLException: ERROR: operator does not exist: bigint = bytea
Hint: No operator matches the given name and argument types. You might need to add explicit type casts.
I have a solution in mind where I can update the fulfilmentId to a default value like -1 if it is null, but I need to understand why is it failing? What am I missing here?
I was running into similar issue for a native query, which find records with matching column values. When the value for any parameter is null, hibernate uses the wrong type throws casting exceptions. After spending some time I found that in such cases need to use Hibernate's TypedParameterValue
So in your case #Param(value = "fulfilmentId") Long fulfilmentId would be
#Param(value = "fulfilmentId") TypedParameterValue fulfilmentId
Also from the service you need to convert your parameter accordingly from Long to TypedParameterValue as below:
TypedParameterValue fulfilmentIdParam = new TypedParameterValue(StandardBasicTypes.LONG, fulfilmentId);

Querying by value in JSONB field in h2/postgresql

I have following json field in entity:
{"uuid", "uuid2"}
and I want to use #Query to find an entity which contains given uuid in this field. I have found a solution for postgresql (which we are using), but when I try to test it using h2 I get Function JSONB_EXISTS not found exception.
Is it possible to make it work with both postgresql and h2 using same query?
How I am creating a query (this works fine for postgresql, but not for h2):
#Query(
nativeQuery = true,
value = "SELECT * FROM patient_person WHERE jsonb_exists(patient_reference_ids, :patientReferenceId)"
)
fun findByPatientReferenceId(#Param("patientReferenceId") patientReferenceId: String): PatientPersonEntity?
How is field defined in entity:
#Type(type = "jsonb")
#Column(columnDefinition = "jsonb")
var patientReferenceIds: emptyList()
Error during test run
Caused by: org.h2.jdbc.JdbcSQLSyntaxErrorException: Function "JSONB_EXISTS" not found; SQL statement:
SELECT * FROM patient_person WHERE jsonb_exists(patient_reference_ids, ?) [90022-200]

Spring JPA: Find all records from the past or now

I have entity Ticket which has a field nextActionDate as Date/Timestamp.
I am heavily unclear how to select all records which are due to an update, i.e. is either now or in the past (with additional parameters).
In my JPARepository I want to annotate the method like
#Query("FROM Ticket t WHERE ... AND !t.nextActionDate.after(new Date())")
List<Ticket> findOpenedMail();
But this fails with expecting '=', found 't'. Also I am not sure if new Date() will be calculated at the time of query - or already pre-prepared when the Bean is created.
So, what is the correct syntax?
You can pass date parameter and use <, > operators in your query:
#Query("FROM Ticket t WHERE ... AND t.nextActionDate < :nextDate ")
List<Ticket> findOpenedMail(#Param("nextDate") Date nextDate);
and call yourRepository.findOpenedMail(new Date());
If you are using mysql you can try annother aproach by changing the date type to Long and save your date in seconds/milliseconds and use the mysql function UNIX_TIMESTAMP(NOW()) (now() is optional) in nativeQuery.
#Query(value = "select * from ticket t where... and t.next_action_date < UNIX_TIMESTAMP()", nativeQuery = true)
List<Ticket> findOpenedMail();
UNIX_TIMESTAMP() will return the current date in seconds.

Converting to correct SQL date stamp results to cast error

My goal is to select all orders from today.
Database format:
system_entry_date = 05-30-2016 12:47:00.0096
$P{today}
java.sql.Date
Is for prompting: Yes
Expression: new java.sql.Date(new java.util.Date().getTime())
$P{sqltoday}
java.sql.Date
Is for prompting: No
Expression: new SimpleDateFormat("dd-MM-yyyy HH:mm").format($P{today})
SQL query: WHERE system_entry_date = $P{sqltoday}
Error: String cannot be cast to java.util.Date
The prompting is 30-6-17 and the SQL date format is 06-30-2017. This the reason that I have used the simpledateformat.
I don't see what's going wrong. Do anyone see the problem? Thanks for any help/tips.

Categories