On Tue, Sep 10, 2019 at 9:21 PM Michael <michae...@gmail.com> wrote:
>
> >I think I would favor (1) , but it has one downside as well: since it
> >already has meaning for date/time's (for example allowing values like
> >"February 31st, 2019", to overflow into "March 3rd, 2019", I think),
> >this would be extending its semantics.
>
> Yes, we are blurring the definition a little of strict vs. lenient, as is 
> currently used in Jackson, with the overflow. However, from these two links, 
> we seem to be within the definition, as an empty string is not "within the 
> outer range of valid values for the field":

True. One nice thing about strict/lenient settings is that there is
already full support for global/per-type/per-property hierarchic
configuration. And for 3.0 we should be able to add "type category"
defaulting between first two categories too ("for all date/time values
use strict unless overridden by type or property").

> Using strict resolution will ensure that all parsed values are within the 
> outer range of valid values for the field. Individual fields may be further 
> processed for strictness.
>
> For example, resolving year-month and day-of-month in the ISO calendar system 
> using strict mode will ensure that the day-of-month is valid for the 
> year-month, rejecting invalid values.
>
> Using lenient resolution will resolve the values in an appropriate lenient 
> manner. Individual fields will interpret this differently.
>
> For example, lenient mode allows the month in the ISO calendar system to be 
> outside the range 1 to 12. For example, month 15 is treated as being 3 months 
> after month 12.
>
> https://docs.oracle.com/javase/8/docs/api/java/time/format/DateTimeFormatter.html#ISO_LOCAL_TIME
>
> https://docs.oracle.com/javase/8/docs/api/java/time/format/ResolverStyle.html#STRICT
>
>
> Now, one question: Would 'strict' be the default in 3.0?

Good question. I am not sure.

I have been burnt a few times by this: the biggest example is default
of Jackson to throw exception on unknown properties. To me that was a
no-brainer -- who would want to defaul to "just ignore the crap",
based on frustration this can lead to with mismatching structures,
quietly passing! -- but many users have claimed this as the most
obnoxious default ever. :-)

So. Maybe? If so (or even if not I suppose) we MUST document it
clearly, and document ways to change it.

>
> If that's the case, option 1 would still work by flipping the logic around, 
> to return null 'if isLenient'. But if 'lenient' is the default, the 
> 'lenient/strict' method wouldn't meet Ruwen's recommendation, which leads to 
> option #3.
>
> >2. Use `ACCEPT_EMPTY_STRING_AS_NULL_OBJECT` -- problem being that it
> >is disabled by default, which is at odds with actual behavior.
>
> >I guess there is also 3rd option: add a setting in Java 8 date/time
> >module itself; something that would be removed from 3.0, if used.
>
> Ok, perhaps 'ACCEPT_EMPTY_STRING_AS_NULL_DATE' which defaults to true in 2.10

Problem here is two-fold: first, I do not want to add many
type-specific Features (although TBH, number of types that need these
is kind of limited; Enums, Date/Time...). Second is my concern is
hierarchic handling, if and how to override it.

> Then removed and then replaced with `ACCEPT_EMPTY_STRING_AS_NULL_OBJECT` in 
> 3.0, which is already defaulted to false.
>
> Given all that, if option 1 looks ok, I can move the PR from Draft-> PR, 
> unless option 3 is a better way to go, and there my biggest question is what 
> exception to throw, maybe the 'weird string'? Thoughts?

Weird String is probably fine.

But now I am bit confused myself on what I actually proposed... so
perhaps before PR, full description on intended change, as an issue
(maybe modify existing one?), to be reviewed, would make sense.

And also phasing wrt 2.10, 3.0.

-+ Tatu +-

> On Tue, Sep 10, 2019 at 12:07 AM Tatu Saloranta <t...@fasterxml.com> wrote:
>>
>> On Sun, Sep 8, 2019 at 5:02 PM Ruwen Schwedewsky
>> <ruwen.schwedew...@messagemedia.com.au> wrote:
>> >
>> > Moin!
>> >
>> > How about delaying this change to 3.0 and then use the lenient option? 
>> > Imho "" and null should be treated differently by default.
>>
>> I think the problem is that as things are right now, "" and `null` are
>> not distinguished by Java 8 date/time deserializers. I agree that a
>> change in default behavior should wait until 3.0, but it seems
>> unfortunate if there is no way to force strict handling with 2.10.
>>
>> If we do want to allow that, it seems to me there are 2 main options:
>>
>> 1. Use `lenient` vs "strict" setting: 2.10 allows global setting
>> (default being "lenient" for backwards compatibility), as well as
>> `@JsonFormat` override for type (class) and property
>> 2. Use `ACCEPT_EMPTY_STRING_AS_NULL_OBJECT` -- problem being that it
>> is disabled by default, which is at odds with actual behavior.
>>
>> I think I would favor (1) , but it has one downside as well: since it
>> already has meaning for date/time's (for example allowing values like
>> "February 31st, 2019", to overflow into "March 3rd, 2019", I think),
>> this would be extending its semantics.
>>
>> I guess there is also 3rd option: add a setting in Java 8 date/time
>> module itself; something that would be removed from 3.0, if used.
>>
>> -+ Tatu +-
>>
>> >
>> > Cheers
>> > Ruwen
>> >
>> > On 7/9/19 2:52 am, Michael O'Keeffe wrote:
>> >
>> > Hi all,
>> >
>> > This is a request for feedback on how to distinquish null from empty 
>> > string for LocalDate and LocalDateTime deserialization, issue #114
>> >
>> > To summarize the issue and possible solutions:
>> >
>> > beytun (issue submitter) writes:
>> >
>> >>>
>> >>> For LocalDate and LocalDateTime deserialization, empty string is mapped 
>> >>> to null by LocalDateDeserializer and LocalDateTimeDeserializer 
>> >>> respectively. So something like {"date": null} can't be distinguished 
>> >>> from {"date": ""}. From the view of a strict API, the latter is an error.
>> >>>
>> >>> It would be good to add some feature to treat empty string as invalid 
>> >>> format, that LocalDateDeserializer and LocalDateTimeDeserializer could 
>> >>> report this as an error instead of mapping to null.
>> >
>> >
>> > Tatu writes:
>> >
>> >> Perhaps use of DeserializationFeature.ACCEPT_EMPTY_STRING_AS_NULL_OBJECT 
>> >> would work here, although my main concern is that since default value is 
>> >> false, adding a check would make formerly accepted values invalid with 
>> >> 2.10...
>> >>
>> >> Alternative way would be to add a new option/feature in JavaTimeModule, 
>> >> where it could be locally enabled/disabled.
>> >
>> >
>> > Now, given beytun's point about 'strict', perhaps another solution is to 
>> > use the lenient/strict setting here? That is already used in 
>> > LocalDateDeserializer to throw an exception:
>> >
>> >
>> >  if (parser.hasToken(JsonToken.VALUE_NUMBER_INT)) {
>> >    if (!isLenient()) {
>> >      return _failForNotLenient(parser, context, JsonToken.VALUE_STRING);
>> >    }
>> >    return LocalDate.ofEpochDay(parser.getLongValue());
>> >  }
>> >
>> > Test case to illustrate issue:
>> >
>> > private final TypeReference<Map<String, LocalDate>> MAP_TYPE_REF = new 
>> > TypeReference<Map<String, LocalDate>>() { };
>> > private final ObjectMapper LOCAL_DATE_MAPPER = newMapper();
>> > private final ObjectReader LOCAL_DATE_READER = 
>> > LOCAL_DATE_MAPPER.readerFor(MAP_TYPE_REF);
>> >
>> > @Test
>> > public void testDeserializationNullAndEmptyString() throws Exception {
>> >  String dateValAsNullStr = null;
>> >
>> >  String valueFromNullStr = 
>> > LOCAL_DATE_MAPPER.writeValueAsString(asMap("date", dateValAsNullStr));
>> >  Map<String, LocalDate> actualMapFromNullStr = 
>> > LOCAL_DATE_READER.readValue(valueFromNullStr);
>> >  assertNull(actualMapFromNullStr.get("date"));
>> >
>> >  String dateValAsEmptyStr = "";
>> >  String valueFromEmptyStr = 
>> > LOCAL_DATE_MAPPER.writeValueAsString(asMap("date", dateValAsEmptyStr));
>> >  Map<String, LocalDate> actualMapFromEmptyStr = 
>> > LOCAL_DATE_READER.readValue(valueFromEmptyStr);
>> >  // this test fails!
>> >  assertNotEquals(actualMapFromEmptyStr,actualMapFromNullStr);
>> > }
>> >
>> >
>> >
>> > Researching a bit, there doesn't seem to be anything in the spec that says 
>> > not to do it as beytun suggests:
>> >
>> > https://stackoverflow.com/questions/9619852/what-is-the-convention-in-json-for-empty-vs-null?noredirect=1&lq=1
>> > https://www.ibm.com/support/knowledgecenter/SSTLXK_7.5.1/com.ibm.wbpm.wid.integ.doc/topics/rjsonnullunsempprops.html
>> >
>> > Speaking of nulls, Tony Hoare calls this his "billion-dollar" mistake. 
>> > Initially I disagreed but now I'm not so sure :)
>> > https://www.lucidchart.com/techblog/2015/08/31/the-worst-mistake-of-computer-science/
>> >
>> >
>> >
>> > --
>> > You received this message because you are subscribed to the Google Groups 
>> > "jackson-dev" group.
>> > To unsubscribe from this group and stop receiving emails from it, send an 
>> > email to jackson-dev+unsubscr...@googlegroups.com.
>> > To view this discussion on the web visit 
>> > https://groups.google.com/d/msgid/jackson-dev/f98b3a71-c408-4eb9-a029-743dcf1f73af%40googlegroups.com.
>> >
>> >
>> > This email and any attachments to it (the "Communication") is, unless 
>> > otherwise stated, confidential, may contain copyright material and is for 
>> > the use only of the intended recipient. If you receive the Communication 
>> > in error, please notify the sender immediately by return email, delete the 
>> > Communication and the return e mail, and do not read, copy, retransmit or 
>> > otherwise deal with it. Any views expressed in the Communication are those 
>> > of the individual sender only, unless expressly stated to be those of 
>> > Message4U Pty Ltd trading as MessageMedia or any of its related entities 
>> > (together “MessageMedia”). MessageMedia does not accept liability in 
>> > connection with the integrity of or errors in the Communication, computer 
>> > virus, data corruption, interference or delay arising from or in respect 
>> > of the Communication.
>> >
>> > --
>> > You received this message because you are subscribed to the Google Groups 
>> > "jackson-dev" group.
>> > To unsubscribe from this group and stop receiving emails from it, send an 
>> > email to jackson-dev+unsubscr...@googlegroups.com.
>> > To view this discussion on the web visit 
>> > https://groups.google.com/d/msgid/jackson-dev/78670562-c800-4048-1dca-b78d76a73efc%40messagemedia.com.au.
>>
>> --
>> You received this message because you are subscribed to the Google Groups 
>> "jackson-dev" group.
>> To unsubscribe from this group and stop receiving emails from it, send an 
>> email to jackson-dev+unsubscr...@googlegroups.com.
>> To view this discussion on the web visit 
>> https://groups.google.com/d/msgid/jackson-dev/CAL4a10jPVf3q7-aZBBqeOP1O%2BSZt8b5WTi7DdSEAvzn0Njb0PA%40mail.gmail.com.
>
>
>
> --
> Note: New e-mail is michae...@protonmail.ch
>
> --
> You received this message because you are subscribed to the Google Groups 
> "jackson-dev" group.
> To unsubscribe from this group and stop receiving emails from it, send an 
> email to jackson-dev+unsubscr...@googlegroups.com.
> To view this discussion on the web visit 
> https://groups.google.com/d/msgid/jackson-dev/CAEBemP14sVqZy0LabBvCHBfuViz1qh0G1ZJ_6KHUkmOLQuGEGQ%40mail.gmail.com.

-- 
You received this message because you are subscribed to the Google Groups 
"jackson-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to jackson-dev+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/jackson-dev/CAL4a10hoktSO9uOh9BLZTYc4grxVDqS6s6y04zMoh%3DwMK9YwAQ%40mail.gmail.com.

Reply via email to