I'd like to write a Predicate which is calculated based on 2 columns.
for example - I have a daysBetween (int) and lastSent (date).
I'd like to know if there's a possibility to perform the following query :
select from X where the last_sent + [some other column which is interval] lessThan now()
something similar to (and I now this is not the correct way to write it..),
builder.between(userData.<Date>get("lastSent").addDays(userIntervals.<Integer>get("interval")),DateUtils.now());
Is there anyway of writing such a query using predicates?
JPA Criteria does not define an addDays() API. You can call a database specific function through the function() API,
See,
http://en.wikibooks.org/wiki/Java_Persistence/Criteria#Special_Operations
Some JPA providers provide extensions to JPQL and Criteria.
See,
http://wiki.eclipse.org/EclipseLink/UserGuide/JPA/Basic_JPA_Development/Querying/Criteria#JpaCriteriaBuilder_and_EclipseLink_Extensions
and,
http://wiki.eclipse.org/EclipseLink/UserGuide/JPA/Basic_JPA_Development/Querying/JPQL#EclipseLink_Extensions_.28EQL.29
Related
Hello experts of the world. Need some help concerning executing a query with SpringData.
The expectation is to execute the Query below in the Spring Data annotation by combining with the repository method name (Automated Query Construction) to get a unique result. Apparently it fails from time to time by saying the result is not Unique.
The question here is if the method name is still considered in Query Construction while also executing the query in the annotation.
#Query("SELECT r from Revision r WHERE r.revisionBid = ?1 AND r.revisionStatusId = ?2 ORDER BY r.lastModifiedDate DESC")
Optional<Revision> findFirst(Integer revisionBid, Integer revisionStatusId);
Thanks in advance!
The query creation for limiting to 1 result is defined here with FIRST & TOP included in the method name.
https://docs.spring.io/spring-data/jpa/docs/current/reference/html/#repositories.query-methods.query-creation
I don't think "findFirst" will work when you're using an #Query, as the query will be constructed from HQL expression in the #Query rather than the fluent API passing over the method name. Because of this, when the query returns multiple results, it will throw the exception as the Optional is told to wrap a single returned object, not a collection. Add a LIMIT clause to the HQL query and you should be good.
With regular MySQL I can artificially group records against a common "ID" with a query like
SELECT FLOOR(ID / 4) as GroupID FROM Table;
Assuming my IDs are sequential, this gives me groups of 4 with the same GroupID.
My question is, can this be done in JPA with a CriteriaQuery? I can see there is a CriteriaBuilder.prod() method (which can be used for division), but how to I convert the result to a straight integer?
Ok, I see there are actually conversion methods: http://docs.oracle.com/javaee/6/api/javax/persistence/criteria/CriteriaBuilder.html#toLong%28javax.persistence.criteria.Expression%29
I need to figure out a way to get the index of every entry in a query result, let me show an example:
Suppose we have 3 entries in the Person table.
Willie
Mike
Alan
And I want to query that table to return all it's entries, and I want to know the index in which they are returned, with JPQL
A Pseudo code would be like this:
SELECT [INDEX], p.name FROM Person p ORDER BY p.name
What should I replace [INDEX] with to get a result like this:
1 - Alan
2 - Mike
3 - Willie
Is there a way to do that using JPQL?
You could probably use a database function and call it using FUNC() (EclipseLink) or FUNCTION() (JPA 2.1) from JPQL. EclipseLink also supports SQL() to embed any SQL you want inside JPQL. Or you could use a native query, or just add the index in Java code, since you really don't need to select it from the database.
I know how to use "DISTINCT" in Doctrine 2, but I really need to use "DISTINCT ON (field)" and I don't know how to do this with the QueryBuilder.
My SQL query looks like:
SELECT DISTINCT ON (currency) currency, amount FROM payments ORDER BY currency
And this query works perfect, but I can't use it with the QueryBuilder. Maybe I could write this query on some other way?
I would suggest that the SELECT DISTINCT ON (..) construct that PostgreSQL supports is outside the Object Relational Model (ORM) that is central to Doctrine. Or, perhaps put another way, because SELECT DISTINCT ON (..) is rare in SQL implementations Doctrine haven't coded for it.
Regardless of the actual logic for it not working, I would suggest you try Doctrine's "Native SQL". You need to map the results of your query to the ORM.
With NativeQuery you can execute native SELECT SQL statements and map
the results to Doctrine entities or any other result format supported
by Doctrine.
In order to make this mapping possible, you need to describe to
Doctrine what columns in the result map to which entity property. This
description is represented by a ResultSetMapping object.
With this feature you can map arbitrary SQL code to objects, such as
highly vendor-optimized SQL or stored-procedures.
SELECT DISTINCT ON (..) falls into vendor-optimized SQL I think, so using NativeQuery should allow you to access it.
Doctrine QueryBuilder has some limitations. Even if I didn't check if it's was possible with query builder, I do not hesitate to use DQL when I do not know how to write the query with query builder.
Check theses examples at
http://doctrine-orm.readthedocs.org/en/latest/reference/dql-doctrine-query-language.html#dql-select-examples
Hope this help.
INDEX BY can be used in DQL, allowing first result rows indexed by the defined string/int field to be overwritten by following ones with the same index:
SELECT
p.currency,
p.amount
FROM Namespace\To\Payments p INDEX BY p.currency
ORDER BY p.currency ASC
DQL - EBNF - INDEX BY
I have an entity Event which has fields startDate and endDate. I'd like to select only those events that have at most x days left to the their endDate. I want to do this in JPQL and with only one query. How can I do this?
JPA does not provide any standard date/time functions. You can use a native SQL query using SQL EXTRACT,
Or, if you are using EclipseLink you can use the FUNC JPQL operator to call a database specific function, or use EXTRACT if using EclipseLink 2.4,
See,
http://wiki.eclipse.org/EclipseLink/UserGuide/JPA/Basic_JPA_Development/Querying/JPQL#Functions