Always save date to today's date in database using jhipster - java

I have created one entity in jhipster using jhipster-jdl.jh file which is as shown below:
entity EmployeeLeave{
appliedDate LocalDate required,
fromDate LocalDate required,
toDate LocalDate required,
status String
}
From these fields i want appliedDate as today's date in database(MySql).
I have tried this from Angular side in jhipster code but none helps well.
Is there any way so that when creating a record for employeeLeave there should be always appliedDate equals to today's date.
Preferably i want solution from Angular side. Other solutions are also welcomed.
Technologies:
Database: Mysql,
Spring-boot,
Angular 4,
Jhipster.

You can initialize your date inside your class :
public class EmployeeLeave{
LocaleDate yourDate = LocaleDate.now();
//other fields
}
So, appliedDate will always be today's date. I am using Java 8 but the idea is here.

LocaleDate.now() is server time. If server is in another time zone than user, may insert incorrect date.
Isn't better to define date in .controller.js like:
var now = new Date();
vm.employeeLeave.appliedDate=now;
vm.isSaving = true;
EmployeeLeave.update(vm.employeeLeave, onSaveSuccess, onSaveError);
?

Related

How can we dynamically change the timezone in java rest api response?

We have api: call_summary/
{
"id": 2,
"number: "xyz",
"call_time": "2021-10-11T03:50:23Z"
}
We have multiple users with various timezones like ADT, EDT, IST, etc. When users access this API the call_time should change according to user timezone. I tried to use #JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "IST"), but this won't allow us to change the call_time dynamically.
Is there any way to do it using annotations or filters?
I would recommend storing call_time in two columns, UTC and users local time-zone.
By doing so, it will eliminate complexity and confusion at both ends (server and client)
Check the following link, it may help you: Pass browser timezone to the backend springboot application to generate reports with dates as per the browser timezone. According to the latter, you can use TimeZone as input to your controller. You could do something like the following:
#RestController
public class TestController {
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm");
#GetMapping(value = "/test")
public String generate(TimeZone timezone) throws IOException {
return LocalDateTime.now().atZone(timezone.toZoneId()).format(formatter);
}
}
Alternatively, you could get the timezone from HttpServletRequest.
JSON Serialize is the best fit for this custom data conversion as per user or user role. I created the converter class and called by #JsonSerialize(converter = LocalDateTimeToStringConverter.class) and #JsonDeserialize(converter = StringToLocalDatetimeConverter.class). It worked as per my expection.
For reference, I attached the sample link below.
Custom conversion using JSON-Serialize-Deserialize

JPA - Returning entities that are After StartDate and Before EndDate

I have two dates in my entity. ie.
Date startDate;
Date endDate;
How do I query so that given a date, it will return all entities where the specified date lies between startDate and endDate?
I already tried the following:
findByStartDateAfterAndEndDateBefore(Date givenDate);
And Spring-Data-JPA didn't like this and running into errors. There is no specific error and the repo just can't be injected to my class.
What is the correct way? I know this can be done easily wqith Hibernate criteria or with Native SQL but trying to do that in Spring JPA.
Is this a problem with the query itself or some sort of incompatibility between the Date types Spring uses?
Tried findByStartDateAfterAndEndDateBefore(Date givenDate, Date givenDate) and that returns null however.
You can't use only one parameter because of Spring Data restrictions, but you can workaround it using code like this:
List<AnEntity> findByStartDateBeforeAndEndDateAfter(Date startDate, Date endDate);
default List<AnEntity> findByStartDateBeforeAndEndDateAfter(Date givenDate) {
return findByStartDateBeforeAndEndDateAfter(givenDate, givenDate);
}
This code should cover your needs. I also verified it with Spring Boot 1.5.9. using spring-data-get-started example.
To my surprise LessThan and GreaterThan working and Before and After failing badly.
I never thought I can use less than and greater than for dates and always look at date related functions like between, before, after.
That's mostly because of the documentation example
After
findByStartDateAfter
… where x.startDate > ?1
Before
findByStartDateBefore
… where x.startDate < ?1
So I looked more close into docs of Spring Data JPA and found something interesting with the below example
LocalDate date = new LocalDate().minusYears(2);
return builder.lessThan(root.get(_Customer.createdAt), date);
So while comparing datatime the authors using the criteria lessthan for time property.
So given a shot with less than and worked and again gave a shot with greater than aswell and later together. So I came up with a conclusion
public MyDateEntity findByStartDateLessThanAndEndDateGreaterThan(Date sDate, Date eDate);
And this is working so far. And I believe, there must be a clean way to handle dates probably with before,after,between but I just can't figure that out.
Would be great if someone figure that out.
You are using AND condition in your JPA query but providing only one parameter. You should use like findByStartDateAfterAndEndDateBefore(Date startDate, Date endDate);
Since you only need the Date object as an equivalent of LocalDate, this should do the trick.
default List<AnEntity> findByStartDateAfterAndEndDateBefore(Date startDate, Date endDate) {
Calendar cal = Calendar.getInstance();
cal.setTime(endDate);
cal.add(Calendar.DATE, -1);
return findByStartDateBetween(startDate, cal.getTime());
}
Because you want it to include the start, but not the end, and SQL BETWEEN is inclusive, we just move the end one day back.
Public List<EntityClass> findData(Date startDate,Date endDate)
{
Query<EntityClass> _q = em.createQuery("select a.* from _tableName a
where a.startDate>= :d1 AND a.endDate<= :d2");
_q.setParameter("d1", startDate, TemporalType.DATE);
_q.setParameter("d2", endDate, TemporalType.DATE);
List<EntityClass> result = query.getResultList();
em.getTransaction().commit();
return result;
}
I use it with no problems like this:
findAllByEntityNotNullAndDateBetween(Date begin, Date end);
Have you already tried it?

DateTime withTimeAtStartOfDay with timezone

could somebody help or give me some hint with following problem. I have trouble with creating Timestamp in Java. In my db i have timestamp stored in UTC time for example 2016-10-20 23:30:00.000000 and my timezone is Europe/Prague so time is +1 Hour. And if i want to select records from 2016-10-21 i have to select also records from 2016-10-20 23:00:00.000000 if i want to have correct results. I am using Postgresql and JOOQ.
public DateTime getDateTimeWithZone() {
return new DateTime().withZone(MyFormatter.getDateTimeZone());
}
This code is in service class Localization service.
Then in controller i create joda time Interval.
Interval range = new Interval(localizationService.getDateTimeWithZone().withTimeAtStartOfDay(), localizationService.getDateTimeWithZone().withTimeAtStartOfDay().plusDays(1));
This gives me
2016-10-21T00:00:00.000+01:00/2016-10-22T00:00:00.000+01:00
and then in method for selecting records from db via JOOQ i use this construction
Timestamp start = new Timestamp(dtRange.getStartMillis());
Timestamp end = new Timestamp(dtRange.getEndMillis());
and result is
start = 2016-10-21 00:00:00.0
end = 2016-10-22 00:00:00.0
but i need to have start and end one hour back
Also i tried to modify method getDateTimeWithZone() with UTC time
public DateTime getDateTimeWithZone() {
return new DateTime().withZone(DateTimeZone.UTC);
}
range is the same. I think problem is with .withTimeAtStartOfDay() but in this case i need to have .withTimeAtStartOfDay() return 2016-10-20 23:00:00.0000. Is there any way how to do it with joda time or new java.time or write some own implementation od DateTime and override .withTimeAtStartOfDay() to return shifted DateTime. I will appreciate any help.

Query on Date only with Spring Boot Data JPA / Java 8 Instant?

I have a Spring boot 1.4.x application that uses the starter jpa in combination with H2/Postgresql. I have an entity that stores a date as an Instant (with Instant.now(), based on Java 8: What's the difference between Instant and LocalDateTime? answer), and the associated table stores this field as a timestamp.
For the storing to work I had to setup a converter that converts Instant's to sql.Timestamps & vice versa, which seems to work (Timestamp.from(instant) and timestamp.toInstant())
My question is if there is a straightforward way to query by Date only using this instant using JPA repository, eg.
List<Orders> findBySaleTime(.... day)
Or am I forced to find a way to convert the day to two instants & do an in between query?
There are two approaches:
1st one:
List<Orders> findBySaleTimeBetween(DateTime start, DateTime end);
2nd one:
List<Orders> findBySaleTime(DateTime date);
It's worth trying to save dates rounded as much as possible, so if you only need day, set hours and minutes to certain values for all the entities.
public List<SaleOrder> findByDate(String date) {
Instant startOfDay = Instant.parse(date).truncatedTo(ChronoUnit.DAYS);
Instant endOfDay = startOfDay.plus(Duration.ofDays(1));
return saleOrderRepository.findBySaleTimeAfterAndSaleTimeBefore(startOfDay, endOfDay);
}
Where the date is an UTC date passed from the client, seems to be the most straightforward to do this with java 8 dates. (Credits to Liste & Yawkat on freenode #java for help/pointers)

request.getParameter String value pass as date to java

In my JSP page I have a field which is date and when I getting as request.getParameter("dateVal"); gives me
15-Dec-2012 12:21.
I would like to pass this value to my database procedure and insert/update into table.
How can I pass the value as setDate using prepareCall to database?
Thanks
First step would be using SimpleDateFormat to parse it to a fullworthy java.util.Date instance in the controller:
Date date = new SimpleDateFormat("dd-MMM-yyyy HH:mm.", Locale.ENGLISH).parse(dateVal);
Then you can just create a java.sql.Date around its time in the database layer:
statement.setDate(1, new java.sql.Date(date.getTime()));
Unrelated to the concrete problem, please note that java.sql.Date doesn't remember the time part. If you have actually a DATETIME or TIMESTAMP field in the DB and not a DATE field, then rather use setTimestamp() with a java.sql.Timestamp instead. This way the time part will also be stored.
#BalusC 's answer is perfect. But as an alternative solution you can use the function provided by database to convert String to Date while querying. For example(in case you use Oracle),
to_date(date_in_String, format)
Try this :
new SimpleDateFormat("dd-MM-yyyy HH:mm").parse(mydate);

Categories