spring jpa auditing with localdate - spring-boot

I want to get a monthly list, weekly list according to created date but JPA doesn't support LocalDate.
My Code like this:
UserDao:
List<User> findByCreatedAtBetween(LocalDate start, LocalDate end);
UserEntity:
#Column(nullable = false, updatable = false)
#Temporal(TemporalType.TIMESTAMP)
#CreatedDate
private LocalDate createdAt;
#Column(nullable = false)
#Temporal(TemporalType.TIMESTAMP)
#LastModifiedDate
private LocalDate updatedAt;
But createdAt and updatedAt only supports java.util.Date. Why doesn't it support java.time.LocalDate?

As you found out LocalDate is currently not supported by Spring Data Envers, or actually in Spring Data Commons where the relevant code resides.
The reason for this is that these timestamp fields are intended to, well, be time stamps, i.e. specify points in time. LocalDate doesn't do that. The problem is not so much the lack of accuracy, but that LocalDate and its sibling LocalDateTime do not define an ordering. It is perfectly possible that something that happened on the Jan 1st, 1970 happened after something else that happened on Jan 2nd, 1970. For more detail refer to the JavaDoc or to http://blog.schauderhaft.de/2018/03/14/dont-use-localdatetime/
Note that LocalDateTime is supported, but mostly because that was implemented before we did realize that it is the wrong type to use for this purpose.
I highly recommend using Instant as the type for this kind of fields.

Related

(Spring) When using PUT method, #CreationTimestamp fails

I have this API that uses #CreationTimestamp to auto-generate the date when any information is added to the database, and it works. The problem is, when i use the PUT method in a specific information of the database, the generated Date disappears.
This is how things are structured:
...
#Temporal(TemporalType.TIMESTAMP)
#Column(name = "CreationDate", length = 29)
#CreationTimestamp
private Date CreationDate;
...
This is how my PUT method is:
#PutMapping("/SomeURL/{id}")
#ResponseBody
public User editUser(#RequestBody #Valid User T, #PathVariable Integer id) {
return userRepository.save(T);
}
When I use this, the generated Date from the #CreationTimestamp disappears, and that field becomes blank (null).
Why is this happening?
OBS: I dont think is necessary, but this is my POST method:
#PostMapping("/someURL")
public User addUser(#RequestBody #Valid User T) {
return userRepository.save(T);
}
The creation date will be updated when calling save method within your editUser method. The entity possibly does not contain this value, therefore null will be set as updated value. (you can try to debug this to check)
Change the column annotation as followed:
#Column(name = "CreationDate", length = 29, nullable = false, updatable = false)
This should prevent the once created date to be updated.
HTH

Hibernate - toString() of a Temporal Column returns different results

With an entity:
class RequestForm {
#Column
#Temporal(TemporalType.TIMESTAMP)
private Date dateCreated;
#Column
#Temporal(TemporalType.TIMESTAMP)
private Date dateUpdated;
// Other hibernate columns...
}
When I retrieve the RequestForm entity from the database, the format of dateCreated.toString() and dateUpdated.toString() is unpredictable, sometimes it returns 2018-06-12 18:21:43.818 and sometimes Tue Jun 12 18:21:43 PHT 2018
I think it was caused by the #Temporal annotation, is there a way to prevent this? Thank you.
EDIT: If it helps, I am using MySQL 5.7

How to store Joda DateTime in MySQL

I've recently started using Joda time library for my test project.
Particularly i have been enjoying the capabilities of DateTime and functions for its manipulation.
My query is how do you store DateTime in MySql. I am using Spring & Hibernate for my application.
my current entity throws deserialisation errors whenever I try and use it:
#Entity
#Table(name = "test_storage")
public class TestEntity {
#Id #GeneratedValue
private int id;
#Column
private DateTime testDate;
//getters and setters
}
The mysql table structure is as follows:
Name: test_storage
Columns:
id INT NOT_NULL, AUTO_INCREMENT
testDate DATETIME
Any advice?
If you are using Hibernate 4+, then you can adopt the Jadira user types which allow you to map DateTime (and other JODA date time related class like LocalDate, LocalDateTime etc) to DB fields using different strategies.
Your mapping will look like
public class TestEntity {
//...
#Column
#Type(type="org.jadira.usertype.dateandtime.joda.PersistentDateTime")
private DateTime testDate;
}
Read the documents to know how to properly use these types to fit your requirements.
The biggest pitfall that you may face soon is, as Java's Date does not include timezone information nor does it sticks to UTC (JODA's user types still need to map to Timestamp/Date internally), you may want to make sure the way you store does provide proper information. For example, either store the date time as UTC, or store timezone information as a separate field, etc.
DATETIME would be my choice. See some more details at What difference between the DATE, TIME, DATETIME, and TIMESTAMP Types and http://infopotato.com/blog/index/datetime_vs_timestamp

Spring mvc ZonedDateTime conversion to UTC

I woudl ike to convert all java8 ZonedDateTimes into UTC time zone on the server side of the application. I am successfully binding the Java 8 jsr310 date data types into a spring RestController using the #DateTimeFormat.
#RequestMapping(value = "rest/test-date", method = RequestMethod.GET)
public TestCollection findPrivilegesByRoleList(
#RequestParam(value = "local-date", defaultValue = "2015-05-10") #DateTimeFormat(iso = ISO.DATE) LocalDate requestParamDate,
#RequestParam(value = "local-date-time", defaultValue = "2015-05-16T15:55:56") #DateTimeFormat(iso = ISO.DATE_TIME) LocalDateTime requestParamLocalDateTime,
#RequestParam(value = "zoned-date-time", defaultValue = "2015-05-18T11:55:56-04:00") #DateTimeFormat(iso = ISO.DATE_TIME) ZonedDateTime requestParamZonedDateTime
)
For the ZonedDateTime class, I would like to shift all input ZonedDateTimes to UTC time, so the server side is always working in UTC timezone. Following best practice #3 - Store it in UTC
http://apiux.com/2013/03/20/5-laws-api-dates-and-times/#comments
For JSON deserialization, I have a custom deserializer for ZonedDateTime that shifts any timezone into UTC.
....
//Parse string into a zoned date time with the specified timezone offset - EST, CET, EDT, PST, ect.
ZonedDateTime zonedDateTimewithTimeZone = ZonedDateTime.parse(string, formatter);
//Shift the date time to UTC Time
return zonedDateTimewithTimeZone.withZoneSameInstant(ZoneId.of("UTC"));
What is the best way to do the conversion in the controller binding? I understand this may be forcing multiple responsibilities into the same class, however I want to avoid adding the
ZonedDateTime.withZoneSameInstant
call for every date in every controller.
Thanks

Post a Joda LocalDateTime as a property. Spring MVC

I have to controller that takes a controller that a Notification and returns a json response.
public #ResponseBody ResponseWrapper<Notification> addNotification(
#RequestParam(required = false) String password,
#Valid Notification notification,
BindingResult bindingResult ){.....}
My Notification that is posted includes a LocalDateTime.
notification.time
How can map a String to LocalDateTime when posting. CustomPropertyEditor or is there a better approach.
Also the time is in my wrapper. How can I format it? LocalDateTime in json includes a lot of information I don't need.
You can annotate your field with #DateTimeFormat and provide a pattern. For example
#DateTimeFormat(pattern = "yyyy-MM-dd")
private LocalDateTime time;
If Spring finds jodatime on your class path, it will use an appropriate DateTimeFormatter to parse the String date value from the request and generate a LocalDateTime object.

Resources