Creation and editing in the Spring Framework

Asked

Viewed 192 times

0

I recently started to learn Spring, along with the Thymeleaf template engine for data display. However, I have been facing some problems that I cannot solve:

  1. When editing the Star Wars Movie entity, I cannot retrieve the "Releasedate" field and set it in the date input of the form. When I change the type of input to text, this specific data ends up being displayed, but I would like it to be done in a date input (which is the most appropriate).
  2. When I submit the "movieForm" form, both in the creation and in the editing of a movie, there is a conversion problem also of the "Releasedate" field. Spring points out that there is incompatibility between the String type (sent from the form) for the Date type (related to the bank). How could you solve this conversion problem?
  3. This problem is related to the others, and it is also an error when submitting the "movieForm" form. I can’t save the data sent in either the creation operation or the editing operation. I imagine it’s some mistake I made in the Conversion classes (inside the package converters), but I’ve been looking for it for days and can’t solve it.

Star Wars Movie Controller

    package example.starwars.controllers;

    import example.starwars.command.StarWarsMovieCommand;
    import example.starwars.services.StarWarsMoviesService;
    import lombok.extern.slf4j.Slf4j;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Controller;
    import org.springframework.ui.Model;
    import org.springframework.web.bind.annotation.*;

    @Slf4j
    @Controller
    public class StarWarsMovieController {
    private StarWarsMoviesService starWarsMoviesService;

    @Autowired
    public StarWarsMovieController(StarWarsMoviesService starWarsMoviesService) {
        this.starWarsMoviesService = starWarsMoviesService;
    }

    @RequestMapping({"/", "", "index"})
    public String getIndexPage(Model model) {
        model.addAttribute("movies", starWarsMoviesService.getStarWarsMovies());
        return "index";
    }

    @GetMapping
    @RequestMapping("/movie/{id}/show")
    public String showById(@PathVariable String id, Model model){
        log.debug("Getting Episode " + id + " page!");
        model.addAttribute("movie", starWarsMoviesService.getStarWarsMovie(Long.valueOf(id)));
        return "movie/show";
    }

    @GetMapping
    @RequestMapping("/movie/new")
    public String newMovie(Model model){
        model.addAttribute("movie", new StarWarsMovieCommand());
        return "movie/movieform";
    }

    @GetMapping
    @RequestMapping("{movieName}/{id}/edit")
    public String updateMovie(@PathVariable String id, @PathVariable String movieName, Model model) {
        log.debug("Editing " + movieName);
        model.addAttribute("movie", starWarsMoviesService.findCommandById(Long.valueOf(id)));
        return "movie/movieform";
    }

    @GetMapping
    @RequestMapping("/movie/{id}/delete")
    public String deleteStarWarsMovie(@PathVariable String id){
        log.debug("Deleting Episode " + id);
        starWarsMoviesService.deleteStarWarsMovie(Long.valueOf(id));
        return "redirect:/";
    }

    @PostMapping
    @RequestMapping("movie")
    public String saveOrUpdate(@ModelAttribute StarWarsMovieCommand starWarsMovieCommand) {
        StarWarsMovieCommand savedCommand = starWarsMoviesService.saveStarWarsMovieCommand(starWarsMovieCommand);
        return "redirect:/movie/" + savedCommand.getId() + "/show";
     }
   }

Star Wars Movie Model

package example.starwars.models;

import lombok.*;

import javax.persistence.*;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

@Data
@Entity
public class StarWarsMovie {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;

private String movieName;
@Column(columnDefinition = "DATE")
private Date releaseDate;
private Long boxOffice;

@ManyToOne
private Director director;

@ManyToMany
@JoinTable(name = "starwars_starships",
        joinColumns = @JoinColumn(name = "movie_id"),
        inverseJoinColumns = @JoinColumn(name = "starship_id"))
private List<Starship> starships = new ArrayList<>();

@ManyToMany
@JoinTable(name = "starwars_characters",
        joinColumns = @JoinColumn(name = "movie_id"),
        inverseJoinColumns = @JoinColumn(name = "character_id"))
private List<Characters> characters = new ArrayList<>();

}

movieForm

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8"/>
    <title>Star Wars Movie Form</title>
    <!-- Latest compiled and minified CSS -->
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
</head>
<body>

<div class="container-fluid" style="margin-top: 20px">
    <div class="row">
        <div class="col-md-6 col-md-offset-3">
            <form  th:object="${movie}" th:action="@{/movie/}">
                <input type="hidden" th:field="*{id}"/>
                <div class="pannel-group">
                    <div class="panel panel-primary">
                        <div class="panel-heading">
                            <h1 class="panel-title">Star Wars Movie Information</h1>
                        </div>
                        <div class="panel-body">
                            <div class="row">
                                <div class="col-md-6 form-group">
                                    <label>Movie Name:</label>
                                    <input type="text" class="form-control" th:field="*{movieName}"/>
                                </div>

                                <div class="col-md-6 form-group">
                                    <label>Release Date:</label>
                                    <input type="date" class="form-control" th:field="*{releaseDate}"/>
                                </div>
                            </div>

                            <div class="row">
                                <div class="col-md-3 form-group">
                                    <label>Box Office:</label>
                                    <input type="number" class="form-control" th:field="*{boxOffice}"/>
                                </div>
                            </div>
                        </div>
                    </div>
                    <button type="submit" class="btn btn-primary">Submit</button>
                </div>
            </form>
        </div>
    </div>
</div>
</body>
</html>

I also put the whole project on Github.

1 answer

0

Lucas, regarding your item 1 dataRelease:

You can use the Datetimeformat annotation to inform a mask in your model class. Already in your html when using Thymeleaf you can use the mask defined in the template.

Annotation to put in Template:

@DateTimeFormat(pattern = "dd/MM/yyyy HH:mm:ss")

How to use the mask in html:

th:field="*{{releaseDate}}"

This should also solve item 2.

A good practice is to use the annotation in the template also the annotation to determine the date type of the attribute.

@Temporal(TemporalType.TIMESTAMP)

These small adjustments should solve your problem.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.