Date calculation in Entity - java

I have my entity class like this
#Entity
public class CheckInstrument extends BaseEntity {
public CheckInstrument() {
}
#Column(nullable = false)
private Date currentCheck;
#Column(nullable = false)
private Long periodicity;
#Column
private Date nextCheck;
#Column
private boolean isExpired;`
(getters and setters)
My issues is
Сalculate nextCheck such as adding periodicity(month) to
currentCheck
Calculate isChecked property as comparing nextCheck with current
System Date.

I think your question is a pure date calculation problem, has nothing to do with Hibernate or jpa entity.
all codes are not written in IDE, not tested either:
Calculate nextCheck such as adding periodicity(month) to currentCheck
You may want to check the Calendar class
Calendar cal = Calendar.getInstance();
cal.setTime(currentCheck);
cal.add(Calendar.MONTH,1);
currentCheck = cal.getTime();
Calculate isChecked property as comparing nextCheck with current System Date.
java.util.Date implements Comparable, so you can compare two dates like:
int result = date1.compareTo(date2);
To your question: nextCheck.compareTo(new Date())
IMO, isExpired / overdued shouldn't be added as database field. because it is related current date. It would be better to get that flag by calculation, to make it real time. Well it is anyway up to your requirement.

Related

spring boot repository: check if Date exists

In my reservation-entity i have a column "bookingDate" --> example: "2021-05-10 12:00:00".
So in this object the date and starttime of an user-booking gets displayed.
If a user wants to book a timeslot, i want to check first if the selected timeslot is empty. So i want to query the database by date&startTime.
I tried it with https://www.baeldung.com/spring-data-jpa-query-by-date , but it didnt work. I got the errors: "The annotation #Temporal is disallowed for this location" & "#Temporal cant be used for variables"
these are the relevant classes:
Reservation.java
#Entity
public class Reservation {
#Id #GeneratedValue
private int reservationId;
#DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME)
private LocalDateTime bookingDate;
private int court = 1;
private String playerNames;
private int userIdReservation;
//getter and setters
With the method "findByBookingDate()" i want to query the database, if the selected timeslot is empty...
VerificationClass.java
public boolean validateReservation(Reservation r) {
LocalDateTime tempDate = r.getBookingDate();
if(reservationRepository.findByBookingDate(tempDate)){ // todo: + and Court
logger.getLogger().info(this.getClass().getName() + "||Booking Slot is empty -- Reservation created||");
return true;
}
logger.getLogger().info(this.getClass().getName() + "||Booking Slot is full -- Reservation failed||");
return false;
}
ReservationRepository.java
#Repository
#Repository
public interface ReservationRepository extends JpaRepository<Reservation, Integer>{
#Query("Select r from reservation r where r.booking_date = :tempDate")
boolean findByBookingDate(#Param("tempDate") LocalDateTime tempDate);
}
If I run it like this i always get an "org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'backyardcodersSpringReactApplication'" --> so the application does not successfully start up.
Im very thankful for every tip and critique!
cheers!
Not understood completely. this is just a lead maybe not a perfect solution.
You can use java.time.LocalDateTime . and annotation be like #DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME).
And the query should be like. [the query will check all the reservation for that day]
Select
from reservation_table
Where
timeSlot between ‘2021-05-10 00:00:00’ and ‘2021-05-10 23:59:59’
I copied your code in my local file. Instead of
import org.springframework.data.jpa.repository.Temporal;
I used
import javax.persistence.Temporal;
in your Reservation.java file.
Also this is my very first answer on Stackoverflow.
First of all #Temporal have three different arguments and it can be applied to the variable of type date , time and time stamp.
Usage
#Temporal(Temporal type.DATE)
private Date date;
#Temporal(Temporal type.TIMESTAMP) // INSERT BOTH DATE WITH TIME TILL MILLISECONDS
private Calendar date;
Why not just just extract the localdate from your LocalDateTime and pass it on? and extract the hour and pass it on and query 2 different columns with it.
LocalDateTime.toLocalDate()
LocalDateTime.getHour()

PMD reference to a mutable object of an interface

Similar to this question. I have an interface DateRangeModel:
I use this to automatically validate dates in implementers:
public interface DateRangeModel {
#ApiModelProperty(value = "From date. Must be less than to date.")
#Column()
Date getFromDate();
void setFromDate(Date date);
#ApiModelProperty(value = "To date. Must be greater than to date.")
#Column()
Date getToDate();
void setToDate(Date date);
/**
* Checks that if both dates are populated, a valid date range is used.
*
* #return true if the date is a valid range.
*/
#AssertTrue(message = "To date must be greater than or equal to from date.")
#JsonIgnore
default boolean areDatesValid() {
if (getToDate() != null && getFromDate() != null) {
return !getFromDate().after(getToDate());
}
return true;
}
}
I implement it like this:
#EqualsAndHashCode
#Data
#Builder
public class BirthdayParty implements DateRangeModel {
Date fromDate;
Date toDate;
String name;
}
Which compiles and seems to work, but I get that error when running PMD:
Returning a reference to a mutable object value stored in one of the object's fields exposes the internal representation of the object.
How can I either accomplish what I want (an interface with to/from date validation) without having to implement the setDate methods in all implementers (which I think would defeat the purpose)?
The problem is that java.util.Date is mutable and you return it in your getters. So someone could do this:
BirthdayParty party = ...;
Date fromDate = party.getFromDate();
...
Date someDate = fromDate;
...
// you might not be aware that this also changes the fromDate in party
someDate.setTime(12345678);
There are four things you can do:
Disable the PMD rule.
Suppress the warning everywhere you use one of these a classes.
Don't use Lombok and copy the dates in your setters and getters instead of just storing/returning the reference to a date.
Use java.time.ZonedDateTime (or LocalDateTime) instead of Date. ZonedDateTime is immutable and should not lead to this warning.
I suggest the fourth option. Not only because it gets rid of the PMD warning but also because the new time API in Java 8 is so much better and easier to use than java.util.Date.

Get all the dates from database

I am storing objects with timestamp in the database(Realm).
public class Met extends RealmObject{
private String name;
private int met;
private long timestamp;
}
I want to show them date wise, like grouping them by date.
Since it is a timestamp and will be different for rows of the same day, I am not able to get it to work.
This comes from the backend and I cannot change it to date.
The only idea I have is to add an extra date field, so that it would be easy to query.
Is there a way to achieve this at the query level without any extra fields?
To query by the same day, you could easily set up a query that queries between the start of the day and the start of the next day.
public class Met extends RealmObject {
private String name;
private int met;
#Index
private long timestamp;
}
And
Date startOfDay = //...get start of day
Date startOfNextDay = //... get start of next day;
RealmResults<Met> mets = realm.where(Met.class)
.greaterThanOrEqualTo(MetFields.TIMESTAMP, startOfDay.getTime())
.lessThan(MetFields.TIMESTAMP, startOfNextDay.getTime())
.findAllSorted(MetFields.TIMESTAMP, Sort.ASCENDING);

Mapping from java.time.MonthDay to java.sql.*

We have a case, where we require only the day and the month and thus would use the java.time.MonthDay (Javadocs) to represent that information.
We are aware that we could create our own JPA object for persistence or just use the java.sql.Date object, but that generally requires an unrequired year information.
Another way is to call the method .atYear(int) (Javadoc) (with a fictitious year) on it and receive a java.time.LocalDate (Javadoc), which can be easily converted to java.sql.Date. But this is prone to missunderstandings in the future (and also persist the year information).
Is there some "elegant"/supposed solution for this case? Or is there a replacement for SQL that supports the whole new date and time API for Persistence.
Another case would be java.time.YearMonth (Javadoc).
Thanks for reading!
Since SQL databases don't have a type compatible with MonthDay, use a VARCHAR columns, and simply use toString() and MonthDay.parse().
Or use a custom DateTimeFormatter, if you don't like the --12-03 format.
The default format will correctly sort, as a string.
here are the code snippets:
// column define:
#Column(name = "date", columnDefinition = "mediumint", nullable = false)
#Convert(converter = MonthDayIntegerAttributeConverter.class)
protected MonthDay date;
// converter define:
public class MonthDayIntegerAttributeConverter implements AttributeConverter<MonthDay, Integer> {
#Override
public Integer convertToDatabaseColumn(MonthDay attribute) {
return (attribute.getMonthValue() * 100) + attribute.getDayOfMonth();
}
#Override
public MonthDay convertToEntityAttribute(Integer dbData) {
int month = dbData / 100;
int day = dbData % 100;
return MonthDay.of(month, day);
}
}

Java: JPA classes, refactoring from Date to DateTime

With a table created using this SQL
Create Table X (
ID varchar(4) Not Null,
XDATE date
);
and an entity class defined like so
#Entity
#Table(name = "X")
public class X implements Serializable {
#Id
#Basic(optional = false)
#Column(name = "ID", nullable = false, length = 4)
private String id;
#Column(name = "XDATE")
#Temporal(TemporalType.DATE)
private Date xDate; //java.util.Date
...
}
With the above, I can use JPA to achieve object relational mapping. However, the xDate attribute can only store dates, e.g. dd/MM/yyyy.
How do I refactor the above to store a full date object using just one field, i.e. dd/MM/yyyy HH24:mm?
If you want to also store time information at the database level, use TemporalType.DATETIME:
#Column(name = "XDATE")
#Temporal(TemporalType.DATETIME)
private Date xDate; //java.util.Date
Use a TIMESTAMP column type at the database level (and xDate will be stored as 'yyyy-MM-dd HH:mm:ss.S').
Have you tried changing the #Temporal value to TemporalType.DATETIME? java.util.Date and java.sql.Date both store date and time components, the TemporalType controls which part JPA stored/pays attention to; date, time, or both.

Categories

Resources