FutureOrPresent not working for today... how to set the constraint to DAY or YEAR?

FutureOrPresent not working for today. It throws validation error. Perhaps the time part fails. I only use date, no time part.
How to set the constraint, to compare just days?

From the BeanValidation JavaDoc:
The annotated element must be an instant, date or time in the present or in the future.
Now is defined by the ClockProvider attached to the Validator or ValidatorFactory. The default clockProvider defines the current time according to the virtual machine, applying the current default time zone if needed.
The notion of present here is defined relatively to the type on which the constraint is used. For instance, if the constraint is on a Year, present would mean the whole current year.

Hi,
I dont have any reply since May.
I just wanted to know, if you are going to fix it according to Java Bean Validatin spec or do I have to implement my own Validator?
Thnak you.
Tomas.

@krivopustov @gorelov

Greetings,

We apologize for the late reply. We hope this reply will helps you.

Time & syscalls problem

First of all, can you answer - do you use windows for development?

This issue is casual question for all our forums, this happens because modern OS is not “real-time” systems.
Syscalls on unix and windows are different in their conventions and we can see problems like problem below:

var localDateTimeNow = LocalDateTime.now();
var localDateTimeNowTwo = LocalDateTime.now();
assert localDateTimeNow != localDateTimeNowTwo
  • For unix nothing will happen
  • For windows - we will get exception

Java Bean validation implementation

In Bean Validation nothing checks for opertaion system, so we have a different behaviour in different OSs.

Solution

Yes, easest way to fix this is reimplement your own bean validation factory and validator behaviour.
Like in float comparation, in date-time comparation shoud not use EQUALS operation. Instead of it, use delta and compare this expression(pseudo-code):

abs(nowTimestamp - yourTimestamp) < delta
abs(1000000000 - 1000000001) < 0.01

Or other way to fix this

  • use @Past instead of @PastOrPresent validation.
  • wait for this issue that i created (Github Issue)

Regards,
Jmix team

Hi Dmitry, thank you for your reply.
My runtime is macOS for DEV and Amazon Linux2, both Correto 11.
I dont think this is a problem of Windows.

I found this:

I think I have the same problem.
So the solution should be to set the type to java.time.LocalDate instead of java.util.Date?

Thank you.

Well, the java.time.LocalDate is not the way to go, bacause I get this ERROR:

Exception Description: The type [class java.time.LocalDate] for the attribute [dateOfIssue] on the entity class [class ....ApplicationForm] is not a valid type for a temporal mapping. The attribute must be defined as java.util.Date or java.util.Calendar.

Hello,

About this:

Probably you forget to remove @Temporal(TemporalType.TIMESTAMP) annotation from field. If you want to use LocalDate, this enought:
image

database representation(migration): <column name="DATE_CREATE_B" type="DATE"/>

About @PastAndPresent :

Test:

  1. Create attribute with date class
  2. Add Validation @PastOrPresent
  3. Add into Browser/Edit screens attribute
  4. Start testing.

Test setup: Mac OS, java 11, Jmix 1.5.3

I test several types and cases in UI:

  1. LocalDateTime (stored as TimeStamp, microseconds):
    My time was 16/08/2023 18:53
    If i save Entity with 18:50 or 18:53 → All fine (probably i can try hit accuracy in microseconds, but this enough)
    If i save Entity with 18:54 → I got error.
  2. Date and LocalDate working same:
    16/08/2023, 15/08/2023 → fine
    17/08/2023 → error validation

As you can see - no errors for my tests and my setup.

I can guess, may be also problem YES with Date. Date does not represent which timezone you have. LocalDate probably can solve your problem, but Date and LocalDate are not represent which time did you have when entity had been committed. Instead of it, use any class that can be converted into TimeStamp. The time resolution will solve your problem:
Date/LocalDate comparation:
16/08/2023 18:53 > 16/08/2023 18:54
16/08/2023 == 16/08/2023,
So, i not recommend use Date: when server have time for example 16/08/2023 18:54, user would have already 17/08/2023 00:54 and for server “he will be in future” (because he is in different TimeZone)-> client never pass validation until server hits 17/08/2023.
LocalDate can solve this problem, but quality resolution of time comparison is still poor.

If your problem after this reply would not solved, create demo and describe the playback steps to catch your error and i will try to solve it.

Regards, Jmix team.

Thank you @d.cherkasov.

ad1. The java.time.LocalDate is not working. There is the mapping exception. And I dont use TIMESTAMP, just DATE

ad2. The problem is NOT with @PastAndPresent, it works. The problem is with @FutureOrPresent. I am lost… I only use DATE without time. In the DB there is only DATE. Setting today’s date will fail the validation. :man_shrugging:

Regards Tomas

Please provide code of your attribute mapping.

Hello Konstantin @krivopustov,
thank you for the reply.

Here is an update:

This one is NOT working:
Entity bean, property validation annotation…

@Temporal(TemporalType.DATE)
@Column(name = "TRAVEL_DOC_DATE_OF_EXPIRATION", nullable = false)
@NotNull
@FutureOrPresent(message = "FutureOrPresentErrMsg")
private Date travelDocDateOfExpiration;

This one is working: :grinning:

<dateField id="travelDocDateOfExpirationField" property="travelDocDateOfExpiration" datatype="date" resolution="DAY" caption="msg://15_ValidUntil" responsive="true">
  <validators>
    <futureOrPresent checkSeconds="false" />
  </validators>
</dateField>

So I will place the validator to the UI descriptor XML.

I dont know why the first one is not working.

Thank you.

Tomas

I would prefer the validation at Entity level, because it also applies, when used via REST API, I guess.
But I only use UI at the moment, so I am fine.
Thank you.
Tomas

Hello,
Sorry for the late response, I researched this problem, reproduce it (finally) and create issue for the bug.
Right now working on it to solve this problem.