title: Required argument [GenreSaveDTO dto] not specified
body: <p>I'm currently learning micronaut in java and do an example in this <a href="https://guides.micronaut.io/micronaut-data-access-jpa-hibernate/guide/index.html" rel="nofollow noreferrer">site</a>. But everything seems doesn't work as I expected</p>
  
  <p>Here is some code:</p>
  
  <p>CrudRepository.java</p>
  
  <pre class="lang-java prettyprint-override"><code>public interface CrudRepository&lt;T, ID extends Serializable&gt; {
  
      Optional&lt;T&gt; findById(@NotNull ID id);
  
      T save(@NotBlank String name);
  
      void deleteById(@NotNull Long id);
  
      List&lt;T&gt; findAll(@NotNull SortingAndOrderArguments args);
  
      int update(@NotNull ID id, @NotBlank String name);
  }
  </code></pre>
  
  <p>GenreRepository (actually same as GenreRepositoryImpl like any others convention in spring webapp)</p>
  
  <pre class="lang-java prettyprint-override"><code>public class GenreRepository implements CrudRepository&lt;Genre, Long&gt; {
  
      @PersistenceContext
      private EntityManager entityManager;  
      private final AppConfig appConfig;
  
      public GenreRepository(@CurrentSession EntityManager entityManager,
                                 AppConfig appConfig) { 
          this.entityManager = entityManager;
          this.appConfig = appConfig;
      }
  
      @Override
      @Transactional(readOnly = true) 
      public Optional&lt;Genre&gt; findById(@NotNull Long id) {
          return Optional.ofNullable(entityManager.find(Genre.class, id));
      }
  
      @Override
      @Transactional 
      public Genre save(@NotBlank String name) {
          Genre genre = new Genre(name);
          entityManager.persist(genre);
          return genre;
      }
  
      @Override
      @Transactional
      public void deleteById(@NotNull Long id) {
          findById(id).ifPresent(genre -&gt; entityManager.remove(genre));
      }
  
      private final static List&lt;String&gt; VALID_PROPERTY_NAMES = Arrays.asList("id", "name");
  
      @Transactional(readOnly = true)
      public List&lt;Genre&gt; findAll(@NotNull SortingAndOrderArguments args) {
          String qlString = "SELECT g FROM Genre as g";
          if (args.getOrder().isPresent() &amp;&amp; args.getSort().isPresent() &amp;&amp; VALID_PROPERTY_NAMES.contains(args.getSort().get())) {
                  qlString += " ORDER BY g." + args.getSort().get() + " " + args.getOrder().get().toLowerCase();
          }
          TypedQuery&lt;Genre&gt; query = entityManager.createQuery(qlString, Genre.class);
          query.setMaxResults(args.getMax().orElseGet(appConfig::getMax));
          args.getOffset().ifPresent(query::setFirstResult);
  
          return query.getResultList();
      }
  
      @Override
      @Transactional
      public int update(@NotNull Long id, @NotBlank String name) {
          return entityManager.createQuery("UPDATE Genre g SET name = :name where id = :id")
                  .setParameter("name", name)
                  .setParameter("id", id)
                  .executeUpdate();
      }
  
  }
  </code></pre>
  
  <p>GenreSaveDTO.java </p>
  
  <pre class="lang-java prettyprint-override"><code>public class GenreSaveDTO {
  
      @NotBlank
      private String name;
  
      public GenreSaveDTO() {}
  
      public GenreSaveDTO(String name) {
          this.name = name;
      }
  
      public String getName() {
          return name;
      }
  
      public void setName(String name) {
          this.name = name;
      }
  }
  </code></pre>
  
  <p>GenreController.java </p>
  
  <pre class="lang-java prettyprint-override"><code>@Validated
  @Controller("/genres")
  public class GenreController {
  
      protected final GenreRepository genreRepository;
  
      public GenreController(GenreRepository genreRepository) { 
          this.genreRepository = genreRepository;
      }
  
      @Get("/{id}") 
      public Genre show(Long id) {
          return genreRepository
                  .findById(id)
                  .orElseThrow(null); 
      }
  
      @Put("/") 
      public HttpResponse update(@Body @Valid GenreUpdateDTO dto) { 
          int numberOfEntitiesUpdated = genreRepository.update(dto.getId(), dto.getName());
  
          return HttpResponse
                  .noContent()
                  .header(HttpHeaders.LOCATION, location(dto.getId()).getPath()); 
      }
  
      @Get(value = "/list{?args*}") 
      public List&lt;Genre&gt; list(@Valid SortingAndOrderArguments args) {
          return genreRepository.findAll(args);
      }
  
      @Post("/") 
      public HttpResponse&lt;Genre&gt; save(@Body @Valid GenreSaveDTO dto) {
          Genre genre = genreRepository.save(dto.getName());
  
          return HttpResponse
                  .created(genre)
                  .headers(headers -&gt; headers.location(location(genre.getId())));
      }
  
      @Delete("/{id}") 
      public HttpResponse delete(Long id) {
          genreRepository.deleteById(id);
          return HttpResponse.noContent();
      }
  
      protected URI location(Long id) {
          return URI.create("/genres/" + id);
      }
  
      protected URI location(Genre genre) {
          return location(genre.getId());
      }
  }
  </code></pre>
  
  <p>When I run the server and test api by using curl like:</p>
  
  <pre><code>curl -X "POST" "http://localhost:8080/genres" \
       -H 'Content-Type: application/json; charset=utf-8' \
       -d $'{
    "name": "music"
  }'
  </code></pre>
  
  <p>But the console logged this kind of error:</p>
  
  <pre><code>21:10:42.112 [nioEventLoopGroup-1-5] ERROR i.m.h.s.n.c.UnsatisfiedRouteHandler - POST /genres (Bad Request): Required argument [GenreSaveDTO dto] not specified
  </code></pre>
  
  <p>Thanks in advance</p>