Nik
Nik

Reputation: 375

Instantiating POJO (LocalDateTime) from YAML Properties File (Java & Spring Boot)

I am trying to load custom properties from a YAML properties file upon initialization using Spring Boot. I have found countless tutorials on how to do that, and they work. The problem is that I can't seem to find a way how to instantiate POJOS, such as for example LocalDateTime. My code is as shown below.

@Configuration
@ConfigurationProperties(prefix="default-film-showings")
public class FilmShowings {
    private List<FilmShowing> filmShowings;

    //Constructors, Getters, setters etc.

    public static class FilmShowing {
        private Integer id;
        private Film film;
        private Theatre theatre;
        private LocalDateTime dateTime;

        //Constructors, Getters, setters etc.
    }
}

My YAML file is currently as follows

default-film-showings:
  filmShowings:
    - id: 1
      dateTime: 2018-07-13 21:00:00

My problem is that I get the following error upon initialisation

Failed to convert property value of type 'java.lang.String' to required type 'java.time.LocalDateTime' for property 'filmShowings[0].dateTime';

I also tried this variant

default-film-showings:
  filmShowings:
    - id: 1
      dateTime:
        date: 
          year: 2018
          month: 7
          day: 13
        time:
          hour: 21
          minute: 0
          second: 0
          nano: 0

but I got the following error

Error creating bean with name 'filmShowings': Could not bind properties to FilmShowings

Any help? I looked at the following thread JSON Java 8 LocalDateTime format in Spring Boot but it didn't solve my problem.

On a similar note, is there any way to link the Film POJO attribute to another default property?

Say I have the following in my properties file

default-films:
  films:
    - id: 1
      filmName: Spider-Man

can I add something like this too?

default-film-showings:
  filmShowings:
    - id: 1
      film: default-films.films[0]
      dateTime: whatever I need to do here to make it work

It is reading default-films.films[0] as string and thus not matching 'the YAML' object.

Any help?

Upvotes: 1

Views: 5534

Answers (3)

Michel Riondel
Michel Riondel

Reputation: 31

In your Spring Config Class annotate the localdatetime field like this:

@Configuration
@ConfigurationProperties(prefix = "unloadpathinfo")
public class YourConfiguration {

@DateTimeFormat(iso = ISO.DATE_TIME)
private LocalDateTime offset;

In this example offset is the LocalDateTime Attribute we want Spring to inject from application.yml

If you look at the ISO_DATE_TIME you will find the correct pattern

In the Yaml put the config value like this:

unloadpathinfo:
offset: "2024-01-01T01:30:00.000+01:00"

That's all.

Upvotes: 0

Thororm
Thororm

Reputation: 1

You should just adapt the setter in the configuration class.

if your yaml is:

default-film-showings:
  filmShowings:
    - id: 1
      dateTime: 2018-07-13 21:00:00

then do this in your configuration class:

@Configuration
@ConfigurationProperties(prefix="default-film-showings")
public class FilmShowings {
    private List<FilmShowing> filmShowings;

    //Constructors, Getters, setters etc.

    public static class FilmShowing {
        private Integer id;
        private Film film;
        private Theatre theatre;
        private LocalDateTime dateTime;

        //Constructors, Getters, setters etc.
        public void setDateTime(String dateTime) {
          DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd 
          HH:mm:ss");
          LocalDateTime formatDateTime = LocalDateTime.parse(dateTime, formatter);
          this.dateTime= formatDateTime;
        }
    }
}

Upvotes: -1

Abhijit Sarkar
Abhijit Sarkar

Reputation: 24637

  1. Assuming Spring honors the @DateTimeFormat annotation in a @ConfigurationProperties class (I haven't verified that), you've declared the format to be DateTimeFormat.ISO.DATE_TIME which is 2011-12-03T10:15:30+01:00[Europe/Paris]. Your property file has 2018-07-13 21:00:00 which isn't any of the standard formats. How do you expect it to work?

  2. Your datatype is LocalDateTime which doesn't have a concept of time zone, thus contradicting the ISO_DATE_TIME format. However, the time zone is optional is for ISO_DATE_TIME, so this may not be an issue.

Clearly, you're throwing spaghetti at the wall and hoping something would stick. Write a unit test and try to convert the string to whatever datetime object you want. Once you've done that, come back if you've a problem.

Upvotes: 4

Related Questions