I have a persistent object with two Date fields, like this
#Temporal(TemporalType.TIMESTAMP)
private Date generated;
#Temporal(TemporalType.TIMESTAMP)
private Date expirationTime;
On object construction the expirationTime is initialized based on the generated field
this.expirationTime = new Date(generated.getTime() + ttlMillis);
Now I'm trying to delete all expired objects from the database with a JPA query
Query q = em.createQuery("delete from MyObject t where CURRENT_TIMESTAMP > t.expirationTime");
q.executeUpdate();
But running a simple test
MyObject o = new MyObject(somePastDate, someTTL);
em.persist(o);
... create the query above
q.executeUpate();
shows no row is being deleted. Any clue on what I'm doing wrong? I'm running tests on HSQLDb and using Hibernate as my JPA provider.
Edit: solved, but I'm not sure why this version should work differently.
Query q = em.createQuery("delete from MyObject t where :now > t.expirationTime");
q.setParameter("now", new Date());
q.executeUpdate();
What's the use of CURRENT_TIMESTAMP if comparisons with other fields fail?
You did not set any parameter, and the query has to get a named parameter:
Query q = em.createQuery("delete from MyObject t where CURRENT_TIMESTAMP > :expirationTime");
q.setParameter("expirationTime" , yourObject.getExpirationTime());//or your getter
q.executeUpdate();
I add a link to enforce the topic here.
Check if it works :-)
Related
#Query("from PrsBookingProcess pbp where (:bookingOwnerCode='' OR pbp.bookingOwnerCode = :bookingOwnerCode)"
+ "and (pbp.crtDttime BETWEEN :fromDate AND :toDate)"
+ "and (:bookingProcStatus is null OR pbp.bookingProcStatus = :bookingProcStatus)"
List<PrsBookingProcess> findByPnrbydateRangeandOperator(
#Param("bookingOwnerCode") String bookingOwnerCode,
#Param("fromDate") Calendar fromDate,
#Param("toDate") Calendar toDate,
#Param("bookingProcStatus") String bookingProcStatus);
This is my JPA query to hit Postgres DB. My bookingOwnerCode value takes null only if I check there value with empty quotes(''). If i check by making them :BookingOwnerCode is null and giving them null from UI it will not fetch me records.
As in case of bookingProcStatus. If i do not give any value in UI and run for above query it will not fetch me anything until and unless i give some value to it.
I am using PGAdmin3 for postgrep and JPA for querying.
You could just use :bookingOwnerCode is null OR :bookingOwnerCode = '' instead of just :bookingOwnerCode = ''.
Or you could write a unit/integration test that verifies the expected behaviour.
I'm using hibernate 5 with the hibernate-java8 addon to use LocalDateTime fields. I now have an entity which has a date field and a user field like in:
#Entity
public class Transaction {
// ...
private User user;
private LocalDateTime date;
// ..
}
Now I simply want to query all transactions of a user within a certain time range. So I use the following query:
SELECT t FROM Transaction t WHERE t.user = :owner AND t.date BETWEEN :from AND :to
Strange enough this query does not give me any results. I also tried using the < and > operators but that did not help either. When I leave out the time range part I get the correct list of transactions for the user. When I execute the SQL query generated by Hibernate in the MySQL workbench I also get the expected results. I use the following snippet to execute the (named) query:
public <T> List<T> findList(Class<T> type, String queryName,
Map<String, Object> params) {
final EntityManager em = this.entityManager.get();
final TypedQuery<T> query = em.createNamedQuery(queryName, type);
params.forEach(query::setParameter);
return query.getResultList();
}
This is simply called providing the query listed above and a map of named parameters like:
findList(Transaction.class, Transaction.BY_USER_AND_RANGE,
ImmutableMap.of("owner", owner, "from", from, "to", to));
In my test case a persisted a single Transaction with the current date and created a range from yesterday to tomorrow for the query. Inspecting the table in the MySQL workbench shows that the transaction is there and that the date field has the correct type and contains the correct value. Yet my query won't give me any results.
Is there anything I'm missing?
The date you are passing as param should also be
LocalDateTime
see the example code below might help you
LocalDate date = LocalDate.of(2015, 8, 11);
TypedQuery<MyEntity> query = this.em.createQuery("SELECT e FROM MyEntity e WHERE date BETWEEN :start AND :end", MyEntity.class);
query.setParameter("start", date.minusDays(2));
query.setParameter("end", date.plusDays(7));
MyEntity e = query.getSingleResult();
Can anyone suggest me the solution of fetching data on condition of current date which i am passing in dao layer method of type system current date.
for e.g I have to fetch data from table "X" which have a column "startdate" of Date type(Mysql) on the basis if that date is greater with the current date passed to the query in java.
I have tried with java.util.Date but not working and also my requirement is not to used database specific function like curr() or Now().
I found a relative post but none helped.Is there no alternative apart from using JodaTime.
Thanks.
In your Entity class mark 'startdate' field with
#Column(name = "startdate")
#Temporal(TemporalType.DATE)
private Date startdate;
And create query like this one:
#NamedQuery(name = "Entity.findAfterDate", query = "SELECT e FROM Entity e WHERE e.startdate >= :dateAfter")
In your EntityDAOImpl
public List<Entity> getEntitiesAfterDate(Date date) {
Query query = openSession().getNamedQuery("Entity.findAfterDate");
query.setParameter("dateAfter", date);
return query.list();
}
I'm using an ebean query in the play! framework to find a list of records based on a distinct column. It seems like a pretty simple query but the problem is the ebean method setDistinct(true) isn't actually setting the query to distinct.
My query is:
List<Song> allSongs = Song.find.select("artistName").setDistinct(true).findList();
In my results I get duplicate artist names.
From what I've seen I believe this is the correct syntax but I could be wrong. I'd appreciate any help. Thank you.
I just faced the same issue out of the blue and can not figure it out. As hfs said its been fixed in a later version but if you are stuck for a while you can use
findSet()
So in your example use
List<Song> allSongs = Song.find.select("artistName").setDistinct(true).findSet();
According to issue #158: Add support for using setDistinct (by excluding id property from generated sql) on the Ebean bug tracker, the problem is that an ID column is added to the beginning of the select query implicitly. That makes the distinct keyword act on the ID column, which will always be distinct.
This is supposed to be fixed in Ebean 4.1.2.
As an alternative you can use a native SQL query (SqlQuery).
The mechanism is described here:
https://ebean-orm.github.io/apidocs/com/avaje/ebean/SqlQuery.html
This is from the documentation:
public interface SqlQuery
extends Serializable
Query object for performing native SQL queries that return SqlRow's.
Firstly note that you can use your own sql queries with entity beans by using the SqlSelect annotation. This should be your first approach when wanting to use your own SQL queries.
If ORM Mapping is too tight and constraining for your problem then SqlQuery could be a good approach.
The returned SqlRow objects are similar to a LinkedHashMap with some type conversion support added.
// its typically a good idea to use a named query
// and put the sql in the orm.xml instead of in your code
String sql = "select id, name from customer where name like :name and status_code = :status";
SqlQuery sqlQuery = Ebean.createSqlQuery(sql);
sqlQuery.setParameter("name", "Acme%");
sqlQuery.setParameter("status", "ACTIVE");
// execute the query returning a List of MapBean objects
List<SqlRow> list = sqlQuery.findList();
i have a solution for it:-
RawSql rawSql = RawSqlBuilder
.parse("SELECT distinct CASE WHEN PARENT_EQUIPMENT_NUMBER IS NULL THEN EQUIPMENT_NUMBER ELSE PARENT_EQUIPMENT_NUMBER END AS PARENT_EQUIPMENT_NUMBER " +
"FROM TOOLS_DETAILS").create();
Query<ToolsDetail> query = Ebean.find(ToolsDetail.class);
ExpressionList<ToolsDetail> expressionList = query.setRawSql(rawSql).where();//ToolsDetail.find.where();
if (StringUtils.isNotBlank(sortBy)) {
if (StringUtils.isNotBlank(sortMode) && sortMode.equals("descending")) {
expressionList.setOrderBy("LPAD("+sortBy+", 20) "+"desc");
//expressionList.orderBy().asc(sortBy);
}else if (StringUtils.isNotBlank(sortMode) && sortMode.equals("ascending")) {
expressionList.setOrderBy("LPAD("+sortBy+", 20) "+"asc");
// expressionList.orderBy().asc(sortBy);
} else {
expressionList.setOrderBy("LPAD("+sortBy+", 20) "+"desc");
}
}
if (StringUtils.isNotBlank(fullTextSearch)) {
fullTextSearch = fullTextSearch.replaceAll("\\*","%");
expressionList.disjunction()
.ilike("customerSerialNumber", fullTextSearch)
.ilike("organizationalReference", fullTextSearch)
.ilike("costCentre", fullTextSearch)
.ilike("inventoryKey", fullTextSearch)
.ilike("toolType", fullTextSearch);
}
//add filters for date range
String fromContractStartdate = Controller.request().getQueryString("fm_contract_start_date_from");
String toContractStartdate = Controller.request().getQueryString("fm_contract_start_date_to");
String fromContractEndtdate = Controller.request().getQueryString("fm_contract_end_date_from");
String toContractEnddate = Controller.request().getQueryString("fm_contract_end_date_to");
if(StringUtils.isNotBlank(fromContractStartdate) && StringUtils.isNotBlank(toContractStartdate))
{
Date fromSqlStartDate=new Date(AppUtils.convertStringToDate(fromContractStartdate).getTime());
Date toSqlStartDate=new Date(AppUtils.convertStringToDate(toContractStartdate).getTime());
expressionList.between("fmContractStartDate",fromSqlStartDate,toSqlStartDate);
}if(StringUtils.isNotBlank(fromContractEndtdate) && StringUtils.isNotBlank(toContractEnddate))
{
Date fromSqlEndDate=new Date(AppUtils.convertStringToDate(fromContractEndtdate).getTime());
Date toSqlEndDate=new Date(AppUtils.convertStringToDate(toContractEnddate).getTime());
expressionList.between("fmContractEndDate",fromSqlEndDate,toSqlEndDate);
}
PagedList pagedList = ToolsQueryFilter.getFilter().applyFilters(expressionList).findPagedList(pageNo-1, pageSize);
ToolsListCount toolsListCount = new ToolsListCount();
toolsListCount.setList(pagedList.getList());
toolsListCount.setCount(pagedList.getTotalRowCount());
return toolsListCount;
Below is mysql query which is working fine and giving me expected results on mysql console.
select * from omni_main as t where t.date_time BETWEEN STR_TO_DATE(CONCAT('2011', '08', '01'),'%Y%m%d') AND LAST_DAY(STR_TO_DATE(CONCAT('2012', '08','01'), '%Y%m%d')) group by year(date_time),month(date_time)
I need its JPA equivalent query. Below is what I am trying but its returning nothing.
String queryStr = "select * from OmniMainEntity o where o.dateTime BETWEEN STR_TO_DATE(CONCAT('"+fromYear+"', '"+fromMonth+"','01'), '%Y%m%d') AND "
+"LAST_DAY(STR_TO_DATE(CONCAT('"+toYear+"', '"+toMonth+"','01'), '%Y%m%d'))";
Query query = manager.createQuery(queryStr);
System.out.println("Result Size: "+query.getResultList().size());
Here fromYear, fromMonth, toYear, toMonth are method parameters using in creating queryStr.
Please suggest where I may wrong!
Any other way to achieve goal is also welcome!
As you are using JPA Query, it would be better to not use database-specified sql function, such as STR_TO_DATE.
You can have a try by this way.(A Hibernate way, JPA should be similiar):
First, you can parse a java.util.Date object from "fromYear" and "fromMonth" like below:
DateFormat df = new SimpleDateFormat("yyyyMMdd");
Date startDate = df.parse(fromYear + "" + fromMonth + "01");
Date endDate = df.parse(.....);
Then, set them into the JPA query.
String queryStr = "select * from OmniMainEntity o where o.dateTime BETWEEN :startDate AND :endDate)"; // The query now changed to database independent
Query query = manager.createQuery(queryStr);
query.setDate("startDate", startDate);
query.setDate("endDate", endDate);
At last, doing the search:
System.out.println("Result Size: "+query.getResultList().size());
Your query doesn't have a verb in it. You probably want SELECT in there:
SELECT o FROM OmniMainEntity o WHERE...
Also, you should be using parameterized and typed queries, and it's usual to use short names (o instead of omniMainEnt) to make your queries readable.