0

I'm trying to add a table to the database via a form. The entity being created is called Album and it has 2 fields, Artist and Genre. Each of these two are separate entities. These 2 fields are annotated with @ManyToOne

@ManyToOne
private Artist artist;

@ManyToOne
private Genre genre;

When I submit the form, this is the error im getting:

There was an unexpected error (type=Internal Server Error, status=500).
Error during execution of processor 'org.thymeleaf.spring4.processor.attr.SpringOptionFieldAttrProcessor' (album/add:52)

The following code is part of my controller:

    @RequestMapping({"/add", "/add/"})
public String adminAlbumAdd(Model model) {
    model.addAttribute("album", new Album());
    model.addAttribute("artists", artistService.list());
    model.addAttribute("genres", genreService.list());
    return "album/add";
}

@RequestMapping( value = "/save", method = RequestMethod.POST )
public String save(@Valid Album album, BindingResult bindingResult, Model model) {
    if(bindingResult.hasErrors()) {
        model.addAttribute("artists", artistService.list());
        model.addAttribute("genres", genreService.list());
        return "album/add";
    } else {
    Album savedAlbum = albumService.save(album);
    return "redirect:/album/view/" + savedAlbum.getAlbumId();
    }
}

And the following code is part of the thymeleaf template:

    <div th:class="form-group" th:classappend="${#fields.hasErrors('artist')}? 'has-error'">
            <label class="col-sm-2 control-label">Artist <span class="required">*</span></label>
            <div class="col-md-10">
                <select class="form-control" th:field="*{artist}">
                    <option value="">Select Artist</option>
                    <option th:each="artist : ${artists}" th:value="${artist.artistId}" th:text="${artist.artistFirstName + ' ' + artist.artistFirstName}">Artists</option>
                </select>
                <span th:if="${#fields.hasErrors('artist')}" th:errors="*{artist}" th:class="help-block">Artist Errors</span>
            </div>
        </div>   

        <div th:class="form-group" th:classappend="${#fields.hasErrors('genre')}? 'has-error'">
            <label class="col-sm-2 control-label">Genre <span class="required">*</span></label>
            <div class="col-md-10">
                <select class="form-control" th:field="*{genre}">
                    <option value="">Select Genre</option>
                    <option th:each="genre : ${genres}" th:value="${genre.genreName}" th:text="${genre.genreName}">Genres</option>
                </select>
                <span th:if="${#fields.hasErrors('genre')}" th:errors="*{genre}" th:class="help-block">Genre Errors</span>
            </div>
        </div>    

What is causing this error ?

3
  • where is add.html, could you add the proyect directory tree Commented Jan 13, 2018 at 20:50
  • @JorgeL.Morla It's under resources/album/add.html I highly doubt it's an issue with the project tree because everything else in the project is working fine Commented Jan 13, 2018 at 21:11
  • can you add 51,52,53 lines of add.html, is possible there are some syntax errors. Commented Jan 14, 2018 at 21:35

3 Answers 3

2

The issue turned out to be related to the repository. I was extending CrudRepository, but the id was of type int. Once i changed that, it worked.

Sign up to request clarification or add additional context in comments.

Comments

0

Firstly, you might consider using same mapping for GET/POST requests as a standard like:

@GetMapping("/new")
...
@PostMapping("/new")

Also @Valid Album album parameter should be annotated as @ModelAttribute. You should not add model attributes if binding result has errors. (Actually, you should not add any model attribute for a POST method.) You should not create that savedAlbum object with albumService.save(). That method should be void.

2 Comments

I added the "genres" and "artists" model attributes because i want them to remain loaded in the select list when i redirect back to the form. how else can i achieve that?
You redirect album/add view if binding result has any errors, that view already has "genres" and "artists" attributes. So you just need to set related values of dropdowns.
0

I will advise against posting directly to your database object. You should rather create a DTO class, say AlbumDto, that will map the classes like so:

public class AlbumDto {
...
private long genreId;
private long artistId;

// Getters & Setters

}

You can then convert it to your Album object, lookup the corresponding Genre and Artist in your controller, set them on the Album object and then save.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.