I'm building a Spring-REST-API with CRUD-functionality to create, read, update and delete films with an in-memory H2-database. The basic functionalities for creating new films, getting all films, getting a single film by id, updating a film and deleting a film are working correctly (I tested this out with Postman).

In addition to these basic functionalities the API should also be able to search films by their title, their amount of votes, their amount of stars and their release date.

First of all, this is how I implemented the film-entity (using some Lombok-annotations to reduce boilerplate-code):

@Entity
@Table(name="FILMS")
@Getter
@Setter
@RequiredArgsConstructor
public class Film {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Integer id;

    @Column(name="TITLE")
    private String title;

    @Column(name="VOTES_COUNT")
    private Integer votesCount;

    @Column(name="RELEASE_DATE")
    private LocalDate releaseDate;

    @Column(name="STARS_COUNT")
    private Integer starsCount;

}

My FilmRepository looks like this:

public interface FilmRepository extends CrudRepository<Film, Integer> {

    List<Film> findByTitle(String title);
    List<Film> findByVotesCount(Integer votesCount);
    List<Film> findByReleaseDate(LocalDate releaseDate);
    List<Film> findByStarsCount(Integer starsCount);

}

And this is the method in my Controller-class, which should handle the film search by title, amount of votes, amount of stars and release date:

@RequestMapping("/films")
@RestController
public class FilmController {

    private final FilmRepository filmRepository;

    public FilmController(final FilmRepository filmRepository) {
        this.filmRepository = filmRepository;
    }

    // some other methods for @GetMapping, @PostMapping and so on...


    @GetMapping("/films/search")
    @ResponseStatus(HttpStatus.OK)
    public List<Film> searchFilms(@RequestParam(name = "title", required = false) String title, @RequestParam(name = "votesCount", required = false) Integer votesCount, @RequestParam(name = "releaseDate", required = false) LocalDate releaseDate, @RequestParam(name = "starsCount", required = false) Integer starsCount) {
        if (title != null) {
            return this.filmRepository.findByTitle(title);
        } else if (votesCount != null) {
            return this.filmRepository.findByVotesCount(votesCount);
        } else if (releaseDate != null) {
            return this.filmRepository.findByReleaseDate(releaseDate);
        } else if (starsCount != null) {
            return this.filmRepository.findByStarsCount(starsCount);
        } else {
            return new ArrayList<>();
        }
    }

I did a POST-Request with Postman, which leads to this database-entry:

[
    {
        "id": 1,
        "title": "Test",
        "votesCount": 5,
        "releaseDate": "1998-01-01",
        "starsCount": 5
    }
]

When I now try to do a GET-Request to this URI http://localhost:8080/films/search?title=Test my console is showing me the following error message

DefaultHandlerExceptionResolver : Resolved [org.springframework.web.method.annotation.MethodArgumentTypeMismatchException: Failed to convert value of type 'java.lang.String' to required type 'java.lang.Integer'; For input string: "search"]

and I get a 400 Bad Request back. The error stays the same when I try for example this request http://localhost:8080/films/search?votesCount=5.

Why is my application assuming that a title must be converted to an Integer? I thought I did it correctly with this annotation:

@RequestParam(name = "title", required = false) String title

It would be great if any Spring-JPA-expert could help me. Thanks in advance!

1

There are 1 best solutions below

0
salam_verdim_alana_panyatkasi On

If this body request that you sended, than add @RequestParam("id") Integer id as well into your searchFilms controller method. This error is clearly say that you first send id in your reuqest body that is what you get the exception. if you don't add id in requestparam than delete id property from body request.

[
    {
        "id": 1,
        "title": "Test",
        "votesCount": 5,
        "releaseDate": "1998-01-01",
        "starsCount": 5
    }
]