CURRENT_TIMESTAMP - :delay in seconds for Spring Data Jpa - java

I have the following native query:
... lockTimestamp + :delay SECOND) < CURRENT_TIMESTAMP
That I want to translate to Spring Data Jpa. The thing is that I get an error if I use it like this. I'm wondering if there is a direct translation to Spring Data Jpa or if not, I need to use something like this:
... lockTimestamp < :limitDate
Where limitDate is another Param in the Query calculated like:
DateUtils.addSeconds(new Date(), -delay)

Related

Criteria JPA - Call Postgres CAST function

I'm trying to call a Postgres function with Criteria but it's not working. I need to use the LIKE clause in a UUID field, so I need to convert into VARCHAR first.
The result I need:
SELECT * FROM my_table WHERE cast(uuid as varchar(36)) like '%1234%';
What I'm doing in Criteria:
final Path<UUID> uuidField = from.get("uuid");
var cast = cb.function("cast", String.class, uuidField, cb.literal("as varchar(36)"));
cb.like(cast, String.format("%%%s%%", stringValue));
The query which is being generated:
HQL: select generatedAlias0 from com.MyTable as generatedAlias0 where function('cast', generatedAlias0.uuid, 'as varchar(36)') like '%1234%' order by generatedAlias0.name asc
Error:
2022-08-08 18:38:48,549 WARN [io.ver.cor.imp.BlockedThreadChecker] (vertx-blocked-thread-checker) Thread Thread[vert.x-eventloop-thread-9,5,main] has been blocked for 2393 ms, time limit is 2000 ms: io.vertx.core.VertxException: Thread blocked
at antlr.ASTFactory.make(ASTFactory.java:342)
at antlr.ASTFactory.make(ASTFactory.java:352)
at org.hibernate.hql.internal.antlr.HqlBaseParser.jpaFunctionSyntax(HqlBaseParser.java:4633)
at org.hibernate.hql.internal.antlr.HqlBaseParser.primaryExpression(HqlBaseParser.java:1075)
The log is not so clear (I'm using Quarkus + Hibernate Reactive), but I suspect it crashed in database because the function('cast', generatedAlias0.uuid, 'as varchar(36)').
I think it should be something like: function('cast', generatedAlias0.uuid, as varchar(36)) (without quotes). But I don't know how to achieve this result to test my theory.
How can I call this CAST function?
After investigating some possible solutions (I'm avoiding to create custom database routines) I found something interesting in a answer from another question:
Currently JPA does not have APIs for replace() and cast(string as numeric). But you can use CriteriaBuilder.function(...) to create database native functions if database portability is not critical.
Source: JPA criteria builder: how to replace and cast a string to numeric in order-by?
I don't know if this is documented is some place, but assuming that there is no way to call CAST(x AS y) using Criteria, I tried a workaround to force the UUID to VARCHAR cast without using the probably unsupported CAST function.
I tested this direct SQL query to database:
SELECT * FROM my_table WHERE concat(uuid, '') like '%123%';
And it works. This CONCAT forces the cast to VARCHAR and the LIKE function does his job. Knowing this, I did:
final Path<UUID> uuidField = from.get("uuid");
var cast = cb.function("concat", String.class, uuidField, cb.literal(""));
cb.like(cast, String.format("%%%s%%", stringValue));
Worked perfectly. I hope this help someone else.
As #HaroldH said, it's a weird requirement, but happened in my project.

Dataflow Pipeline - Using dynamic param or query

I am trying to create a dataflow pipeline template, which required me to read data from bigquery. So what i need is to make my query dynamic using like Instant.now() but it seems the query is locked when creating the template
Some Code HERE
Some Code HERE
Some Code HERE
pipeline.apply("ReadFromBigQuery",
BigQueryIO.read(new DataTransformer(MyCustomObject.getQuery()))
.fromQuery(spec.getQuery())
.usingStandardSql()
.withQueryLocation("US")
.withoutValidation()
).apply("do Something 1",
Combine.globally(new CombineIterableAccumulatorFn<MyCustomObject2>())
).apply("do Something 2",
ParDo.of(new SendToKenshoo(param, param2)
);
My query is like this
SELECT * FROM `my-project-id.my-dataset.my-view` where PARTITIONTIME between TIMESTAMP('#currentDate') and TIMESTAMP('#tomorrowDate')
need to replace that #currentDate and #tomorrowDate using Instant.now() or any time function
please give me some example
note : i need to change the date on the code instead on query level like this
SELECT * FROM `my-project-id.my-dataset.my-view` where PARTITIONTIME between DATE_ADD(CURRENT_DATE(), INTERVAL -1 DAY) and CURRENT_DATE()
I'm not sure how you're sending those parameters to the query (via value provider, etc). However, I wouldn't recommend using templates for that because you need dynamic inputs. If you want to do that, I would use Flex Templates: https://cloud.google.com/dataflow/docs/guides/templates/using-flex-templates

Hibernate size of data

i need to receive the size of data (in byte) from a postgres database.
Postgres has this method called: octet_length what is exactly doing what i want.
But i can't find a way to get the same from Hibernate.
So is it possible to receive these information from Hibernate?
It seems that Hibernate register the octet_length function into this dialect.
For example in PostgreSQL8Dialect.java we can see:
registerFunction( "octet_length", new StandardSQLFunction("octet_length", Hibernate.LONG) );
So you can use
Projections.SqlFunction
in your code

Mysql alike date functions in Morphia

I am in progress of migration a JPA/MySQL application to mongodb using morphia. I have some queries like
AND DATE(NOW()) > (DATE(created) + 2)
or
AND ( TIMESTAMPDIFF(MINUTE,kickoff,now()) > 1 )
or
AND DATE(ending) = DATE(NOW())
Is there anything similar in morphia or mongodb?
From your question I understand that you ask for a way to create date queries in MongoDB and how would your write that query in Morphia
The Cookbook for date queries can be found here.
As pointed in the above post, you should use a range query for this.
In MongoDB's shell, for your first query, you would write it like this:
// hope I got the date part right XD
db.posts.find({created: {$lt: new Date().getDate() - 2}});
For range queries morphia has 2 ways:
using the filter method
using directly the comparator methods.
So the first query would become something like this:
myObjDao.createQuery().field("created").lessThan(new Date(System.currentTimeMillis() - 2 * 24 * 3600 * 1000 )).fetch();

Query.setparameter using TemporalTipe.Time

I wanna do SELECT e FROM Pedidos e WHERE e.diaPedido = :diaPedido AND e.horaPedido = :horaPedido.
When I write parameters use query.setParameter("diaPedido", fechaEscogida, TemporalTipe.DATE) and query.setParameter("horaPedido", horaEscogida, TemporalTipe.TIME) but i don´t know why second filter Temporal.TIME doesn´t work because still compare like TIMESTAMP.
I use eclipseLink 2.3.0 and javax.persistence 2.0.1.
diaPedido and horaPedido are both Date in oracle database.
If you want to just compare the time portion of a TIMESTAMP column, you need to use a database function.
In EclipseLink (>=2.4) you can use EXTRACT or CAST, or the FUNCTION/FUNC operator to call a database function.
See,
http://java-persistence-performance.blogspot.com/2012/05/jpql-vs-sql-have-both-with-eclipselink.html

Categories

Resources