0

I have a problem with the serialization of a LocalDateTime of an JPA entity class. I have a class 'Challenge' which contains two dates 'begindate' and 'enddate'.

...
@Column(name = "begindate")
private LocalDateTime begindate;

@Column(name = "enddate")
private LocalDateTime enddate;
...

I already specified a LocalDateTimeAttributeConverter that JPA can convert the LocalDateTime to a Timestamp. I wrote a web application using Jersey which requests my challenge entities from the database. When i test a GET request for an entity, I expect that a date is displayed like "begindate": "2019-09-01T00:00:00+02:00", but my application delivers the attribute in this format:

"begindate": {
    "date": {
        "dayOfWeek": "MONDAY",
        "month": "JULY",
        "year": 2019,
        "dayOfMonth": 1,
        "dayOfYear": 182,
        "era": "CE",
        "monthValue": 7,
        "chronology": {
            "calendarType": "iso8601",
            "id": "ISO"
        },
        "leapYear": false,
        "day": 1
    },
    "dayOfWeek": "MONDAY",
    "hour": 12,
    "month": "JULY",
    "dayOfMonth": 1,
    "dayOfYear": 182,
    "year": 2019,
    "monthValue": 7,
    "nano": 0,
    "time": {
        "hour": 12,
        "nano": 0,
        "minute": 0,
        "second": 0
    },
    "minute": 0,
    "second": 0
}

When I used a GlassFish Server the output was as I expected it. Now I am using TomEE 7 because I had some troubles with the GlassFish Server and here a LocalDateTime gets serialized in JSON. Is it somehow possible to get the output in the above mentioned simple format?

Thanks for your help!

Oliver
  • 21
  • 2
  • It seems that your JSON serialization library is misconfigured. If you're using Jackson, did you register `JavaTimeModule` in `ObjectMapper`? – crizzis Jul 17 '19 at 10:32
  • Where should I register the module in my application? – Oliver Jul 17 '19 at 12:53
  • Wherever `ObjectMapper` is being created. Again, I'm guessing the technology stack you're using. If it's JEE with JAX-RS, I'd first try creating [a provider for `ObjectMapper`](https://stackoverflow.com/a/51852924/1092818). You just need the `objectMapper.addModule(new JavaTimeModule())` line, you'll also want `com.fasterxml.jackson.datatype:jackson-datatype-jsr310` on your classpath for the `JavaTimeModule` – crizzis Jul 17 '19 at 13:16

2 Answers2

0

Tomee 7 is using johnzon mapper for json serialization so you can write a Converter for java.time types and map it through johnzon API: http://tomee.apache.org/tomee-8.0/docs/developer/json/index.html. You can also set a custom impl of provider just passing a customized Mapper instance to JohnzonProvider through a subclass to avoid the annotation on your model and make it global if it is undesired to modify your entities. Just dont forget to set johnzon-jaxrs dependency with scope provided.

Romain Manni-Bucau
  • 3,354
  • 1
  • 16
  • 13
-1

In your case I would add Adapter to your DateTime field in entity. So something like this:

Create class LocalDateTimeAdapter.java

import java.time.LocalDateTime;
import javax.xml.bind.annotation.adapters.XmlAdapter;

public class LocalDateTimeAdapter extends XmlAdapter<String, LocalDateTime> {

    private final LocalDateTimeConverter converter = new LocalDateTimeConverter();

    @Override
    public LocalDateTime unmarshal(String dateTimeString) throws Exception {
        return converter.fromString(dateTimeString);
    }

    @Override
    public String marshal(LocalDateTime localDateTime) throws Exception {
        return converter.toString(localDateTime);
    }
}

And then use it in your entity class:

import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
...

...
    @Column(name = "begindate")
    @XmlJavaTypeAdapter(value = LocalDateTimeAdapter.class)
    private LocalDateTime begindate;

    @Column(name = "enddate") 
    @XmlJavaTypeAdapter(value = LocalDateTimeAdapter.class)
    private LocalDateTime enddate;
...
JokerTheFourth
  • 415
  • 1
  • 6
  • 19