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
Related
My requirement:
fetch ONE object (e.g RetainInfo ) from table RETAIN_INFO if VERSION column has max value
Does CRUD repository support for an interface method like
findOneByMaxRetVersionAndCountry("DEFAULT")
Equivalent db2 sql:
select RET_ID, max(ri.RET_VERSION) from RETAIN_INFO ri where ri. COUNTRY='DEFAULT' group by RET_ID fetch first 1 rows only;
This query selects an ID, but I would actually want the RetainInfo object corresponding the SINGLE row returned by the query.
I prefer to get that without using custom query, i.e using findBy or some other method/interface supported by Spring CRUD.
You could use limiting in combination with sorting (spring data reference:limit query results). Declare a method similar to the following in your CrudRepository interface :
RetainInfo findTopByCountryOrderByRetVersionDesc(String country);
You can also use findFirst to get the first result. Before getting the result, make sure to use Orderby and then the ascending(Asc) or descending(Desc). As an example if you want to order by version and retrieve based on productName
RetainInfo findFirstByProductNameOrderByVersionDesc(String productName);
Spring Data doesn't provide an expression to select a max value. All supported query parts could be found in the Spring 1.2.0.RELEASE docs: Appendix A. Namespace reference or line 182 of org.springframework.data.repository.query.parser.Part.
Also feel free to create a feature request at Spring's Jira page.
I have a timestamp attribute in my oracle 11g database table. I generated JPA entities from table and the timestamp attribute was created as a date entity. I only want to store and retrieve time values into the database. how to do this? I am using eclipseLink2.4
You can use the #Temporal(TemporalType.TIME) annotation
#Temporal(TemporalType.TIME)
private Date value;
Then only the time portion should be stored to the database.
If you're using the JPA Criteria API to create Queries, you should make sure that the Date portion is zero on existing data. I.e. on an Oracle Database if you query the data like select to_char(timecolumn,'dd.mm.yyyy hh24:mi:ss') from sometable the result should look like "01.01.1970 XX:XX:XX". Normally if you're using the JPA to store Time Values with TemporalType.TIME it will take care of that for you. If the Date portion isn't zero you may have problems comparing the time field.
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
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 trouble with select only month or year in JPA
in mysql i write statement follow:
select * from table where Month(date) = 12 ;
and in entity bean i write follow:
select t from table t where Month(t.date) = 12;
but it throw Error !!
PS: sorry i can't attach my stacktrace because i'm not at home :D
sorry but you cant do this with JPA as far as i know. hibernate's hql on the otherside knows stuff like month() hour() and minute().
check this question: JPA Date Arithmetic?
hope that helped
Not part of JPA, and consequently in the role of vendor extensions. Most JPA implementations support it ... and you don't say which one you're using. DataNucleus certainly supports MONTH, YEAR, DAY, HOUR, MINUTE, SECOND.
This might help someone.
Few JPA implementations have built-in support for date/time functions.
EclipseLink
EclipseLink supports EXTRACT allowing any database supported date/time
part value to be extracted from the date/time. The EXTRACT function is
database independent, but requires database support. EXTRACT(YEAR,
model.currencyExchangeDate), but it requires EclipseLink 2.4.x
FUNC allows for a database function to be call from JPQL. It allows calling any database functions not supported directly in JPQL.
To call the DB function MyFunc(a, b, c) use FUNC('MyFunc', a, b, c).
You can try FUNC('YEAR', currencyExchangeDate) to call 'YEAR'
function.
Hibernate
In HQL, you can have date function YEAR(date), MONTH(date), DAY(date)
to extract required details. Other time functions supported are
HOUR(date), MINUTE(date), SECOND(date).
Criteria API
CriteriaBuilder#function() : Create an expression for the execution
of a database function.
CriteriaQuery<IptExchangeratelines> cq = cb.createQuery(IptExchangeratelines.class);
Root<IptExchangeratelines> exRateLine = cq.from(IptExchangeratelines.class);
cq.where(cb.equal(cb.function("year", Integer.class,
exRateLine.get(exRateLine_.currencyExchangeDate)), year)
.and(cb.equal(cb.function("month", Integer.class,
exRateLine.get(exRateLine_.currencyExchangeDate)), month)));