Select Datetime as Date in criteria query - spring

I'm using JPA CriteriaBuilder to select attributes from the database. I have a specific use case that involves Conversion of datetime to date. The Projection segment of the code is as follows.
CriteriaQuery<ResponseDTO> query = cb.createQuery(ResponseDTO.class);
query.multiselect(root.get(MasterPackagesV1_.masterPackageName),
packageJoin.get(PackagesV1_.packageId),
packageJoin.get(PackagesV1_.packageName),
packageJoin.get(PackagesV1_.startSellingDate),
packageJoin.get(PackagesV1_.endSellingDate),
packageJoin.get(PackagesV1_.createdDate),
packageJoin.get(PackagesV1_.modifiedDate),
packagePaymentJoin.get(PackagePaymentPlanV1_.mrp),
packageSubscriptionJoin.get(PackageSubscriptionsV1_.packageSubscriptionId)
);
All of the date attributes are stored as datetime datatype in the MySQL database. I'm want the datetime to be formatted to date. i.e Instead of retrieving the Dates as LocalDateTime I want it to be converted to LocalDate during Instantiation.
I have made changes in the ResponseDTO class accordingly to support LocalDate. Thanks in Advance.

Related

Query by Example Spring Data

I have domain object Person with date fields:
public class Person {
#Id
private Long id;
private Date date
Build example like this:
Person person = new Person();
person.setSomeOtherFields("some fields");
Example<Person> example = Example.of(person);
How i can create example query with date range (search entity contains date greater or equal from some date and less or equal some another date)?
The Spring Data JPA query-by-example technique uses Examples and ExampleMatchers to convert entity instances into the underlying query. The current official documentation clarifies that only exact matching is available for non-string attributes. Since your requirement involves a java.util.Date field, you can only have exact matching with the query-by-example technique.
You could write your own ExampleMatcher that returns query clauses according to your needs.

Laravel Query Builder - Where date is now using carbon

How to get only date on database column, I have difficulties using Carbon on controller:
$data['nowUser'] = User::where('date', Carbon::today()->toDateString())->get();
Date column looks like this in the database:
That is a DATETIME column, so there's no need for additional formatting the Carbon instance. However you need to use whereDate if you want the fetch all users for which the date column contains today's date:
$data['nowUser'] = User::whereDate('date', '=', Carbon::today())->get();
Because when you pass Carbon::today() to the Query Builder method, the __toString method will be automatically called and return a DATETIME string with the format from Carbon::DEFAULT_TO_STRING_FORMAT, which is exactly that MySQL format Y-m-d H:i:s.

Oracle "TIMESTAMP WITH TIMEZONE" Java type mapping issue with raw sql query

I am using an Oracle 11.2 database with column types "TIMESTAMP WITH TIMEZONE" to store time relevant information. I can't change it because it is used by an existing system.
The Java application uses ojdbc7 (v12.1.0.2) + hibernate as JPA provider.
I simplified the following example for easer understanding!
There is an entity "Product" which maps "TIMESTAMP WITH TIMEZONE" columns to java.util.Calendar
#Entity
#Table(name = "PRODUCT")
public class Product {
#Id
#Column(name = "ID")
private String id;
#Column(name = "START_DATE", columnDefinition = "TIMESTAMP WITH TIME ZONE")
private Calendar startDate;
....
}
If I load it through a HQL query it works fine.
1. Issue
If I use a raw sql query:
SELECT * FROM PRODUCT where id='123456';
I get the following exception:
org.hibernate.MappingException: No Dialect mapping for JDBC type: -101
The sql query is a lot more complex I just used a very simple example here. So I can not simply convert it to an HQL query.
2. Issue
If I persist a new product with a start date having a time zone like AEDT. E.g.
2014-01-01 12:00:00 AEDT
it get saved in the database as
01-JAN-14 01.00.00.000000000 UTC
If I query it again from the Java application the Calendar object has the time in UTC as shown above and not the time in AEDT. It is not just a display issue.
The conversion from AEDT to UTC is correct, but the problem is that the information is lost that it was inserted with timezone AEDT.
Is there a way to prevent this? Why is this happening anyway? I searched a lot today, but could not find a good hint.
You can solve the first issue the following way:
First, you need to unwrap the Query implementation. You said that you were using JPA + Hibernate, so:
Query jpaQuery = entityManager.createNativeQuery("select, t.int_c, t.str_c, t.timestamp_c from table t");
SQLQuery hibernateQuery = jpaQuery.unwrap(SQLQuery.class);
(org.hibernate.SQLQuery.class is the wrapped class)
Second, you have to set the type for ALL the columns that you want to retrieve:
hibernateQuery.addScalar("int_c", IntegerType.INSTANCE);
hibernateQuery.addScalar("str_c", StringType.INSTANCE);
hibernateQuery.addScalar("timestamp_c", TimestampType.INSTANCE);
Third, just make the query using the original JPA Query instance
List<Object[]> results = jpaQuery.getResultList();

Extracting timestamp field in Oracle vs MySQL from Grails-Groovy

I am using grails/groovy, and from my controller I am currently doing this for retrieving field from Mysql table containing datetime field
SimpleDateFormat Sformat = new SimpleDateFormat("yyyy-MM-dd");
String format_datenow = Sformat.format(new Date());
String format_dateprevious = Sformat.format(new Date() -31);
String markerCalcQuery =
"select sum(trans_cnt) as t_cnt, location from map2_data where fdate between '"+format_dateprevious+"' and '"+format_dateprevious+"' and res_id = "+res_id+" group by map2_data.location";
res_row=gurculsql.rows(markerCalcQuery);
The above query fails on Oracle11g with error
ORA-01843: not a valid month.
The error I feel is because MySQL stores date in this format: 2011-12-28 02:58:26 and Oracle stores date like this: 28-DEC-11 02.58.26.455000000 PM
How do I make the code generalised, one way is to make the database in Oracle store the date in the same format which I am thinking the way to handle this rather than from the code. If yes, how to change date format in the Oracle db?
Can I specify the format in the grails domain class for map2_data so that no matter what database it is we will have the datetime in the same format.
For several reasons (one being to code database independent - which is basically what you'd need ;-)), it is better to avoid creating SQL statements in your code. Try to use the Grails criteria DSL, e.g. something like
def criteria = YourDomainObject.createCriteria()
criteria.get {
between ('fdate', new Date()-31, new Date())
projections {
sum('trans_cnt')
groupProperty('location')
}
}
(ontested, but should help you get started).
If for some reason you can't use the criteria API, try the fallback to HQL (Hibernate Query Language). I'd always try to avoid to write plain SQL.
In Oracle, dates have their own type, they aren't strings. If you have a string, you should convert it to a date using the TO_DATE function.
String format_datenow = "TO_DATE('" + Sformat.format(new Date()) + "', 'YYYY-MM-DD')";
To make it work also in MySQL, you can create a stored function named TO_DATE that just returns its first argument.

Is there anyway I could use nullable datetime property to get the year?

I am trying to perform the following linq to entities query-
var data = DataContext.Employee.Where(e=>e.Date.Year>1986).ToList();
Now the problem is that Date field is a nullable DateTime field and I can't access Year property and on the database side I can't change legacy code! ....anyways is there anyway possible to use the year property?
var data = DataContext.Employee
.Where(e=>e.Date.HasValue && e.Date.Value.Year>1986).ToList();
Note that this will not include Employees without a date in the list.

Resources