Solucionado (ver solução)
Solucionado
(ver solução)
9
respostas

Dúvida ENUM

Olá , estou fazendo um novo projeto com base nos estudos daqui, mas estou com uma dúvida que não consegui resolver/entender...

Estou fazendo uma API Rest de uma escola de dança, na qual cadastro professoras e alunas, criei um ENUM com as modalidades das aulas, porém devo poder cadastrar mais de uma modalidade para cada professora/aluna, como posso fazer isso? Vou deixar abaixo o meu código, se puderem ajudar, agradeço

Minha Entidade:

package burlesca.escola.api.professoras;

import jakarta.persistence.*;
import lombok.*;

@Table(name = "professoras")
@Entity(name = "Professora")
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
@EqualsAndHashCode(of = "id")

public class Professora {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    private String nome;
    private String email;
    private String telefone;

    @Enumerated(EnumType.STRING)
    private Modalidade modalidade;    

    public Professora(ProfessoraDTO dados) {
        this.nome = dados.nome();
        this.email = dados.email();
        this.telefone = dados.telefone();
        this.modalidade = dados.modalidade();
    }
}

Meu DTO

package burlesca.escola.api.professoras;

import jakarta.validation.constraints.Email;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;

import java.util.List;

public record ProfessoraDTO(
        @NotBlank
        String nome,
        @NotBlank @Email
        String email,
        @NotBlank
        String telefone,
        @NotNull
        Modalidade modalidade){}

Minha classe controller:

package burlesca.escola.api.controller;

import burlesca.escola.api.professoras.ProfessoraDTO;
import burlesca.escola.api.professoras.ProfessoraRepository;
import burlesca.escola.api.professoras.Professora;
import jakarta.validation.Valid;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("/professoras")

public class ProfessoraController {

    @Autowired
    private ProfessoraRepository repository;

    @PostMapping
    @Transactional
    public void cadastrar(@RequestBody @Valid ProfessoraDTO dados){
        repository.save(new Professora(dados));

    }
}

Meu ENUM:

package burlesca.escola.api.professoras;

public enum Modalidade {
    BOLLYWOOD,
    BURLESQUE,
    BALLET,
    SALSA_SHINES;
}
9 respostas

E eu criei meu banco de dados desta forma, e relendo sobre fiquei na dúvida se devo definir a modalidade como um SET...

create table professoras(

    id bigint not null auto_increment,
    nome varchar(100) not null,
    email varchar(100) not null unique,
    telefone varchar(10) not null unique,
    modalidade varchar(100) not null,

    primary key(id)

);

Olá Camila

Para permitir que uma professora ou aluna possa ter mais de uma modalidade cadastrada, você pode utilizar uma lista de modalidades em vez de apenas um enum. Assim, cada professora ou aluna poderá ter uma lista de modalidades associadas a ela.

Aqui está como você pode fazer essa modificação no seu código:

Na sua entidade Professora, altere o campo modalidade para uma lista de Modalidade:

@ElementCollection
@Enumerated(EnumType.STRING)
private List<Modalidade> modalidades;

No seu DTO ProfessoraDTO, altere o campo modalidade para uma lista de Modalidade:

@NotNull
List<Modalidade> modalidades;

Na sua classe ProfessoraController, modifique o construtor da classe Professora para receber a lista de modalidades:

public Professora(ProfessoraDTO dados) {
    this.nome = dados.nome();
    this.email = dados.email();
    this.telefone = dados.telefone();
    this.modalidades = dados.modalidades();
}

Dessa forma, você poderá cadastrar mais de uma modalidade para cada professora ou aluna.

Espero ter ajudado e bons estudos!

Oi Otávio, obrigada pela ajuda. Eu fiz as alterações como mencionou, mas ainda assim não funcionou.... estou recebendo este erro:

Insira aqui a descrição dessa imagem para ajudar na acessibilidade

Oi Camila!

Complementando o Otávio, como no seu caso você deseja que uma professora possa ter múltiplas modalidades, então a modelagem do banco de dados vai precisar ser alterada.

Do jeito que você tinha feito, sua tabela professoras tinha uma coluna chamada modalidade, mas isso somente é válido se o registro de uma professora tiver apenas uma única modalidade. Então, no seu caso você vai precisar ter uma nova tabela, para armazenar as modalidades de cada professora.

Crie uma migration que deve ter um script sql para apagar a coluna modalidade da tabela professoras e também criar a tabela professoras_modalidades:

alter table professoras drop column modalidade;

create table professoras_modalidades(
    professora_id bigint not null,
    modalidade varchar(255) not null,
    
    primary key (professora_id, modalidade),
    constraint fk_professora_modalidade foreign key (professora_id) references professoras (id)
);

E no mapeamento do relacionamento:

@ElementCollection
@CollectionTable(name = "professoras_modalidades")
@Enumerated(EnumType.STRING)
private List<Modalidade> modalidades;

E seu DTO precisa alterar para receber um List de modalidades, ao invés de apenas uma:

@NotNull
List<Modalidade> modalidades

Oi Rodrigo, obrigada!

Eu fiz os ajustes, mas me tira mais uma dúvida, por favor? Eu ainda não estou muito familiarizada com isso tudo....

Alterando então a modelagem do banco de dados, o envio dos dados json seria assim?

{
    "nome": "Marta Rocha",
    "email":"marta@escolaburlesca.com",
    "telefone": "1189999977",
    "professoras_modalidades": ["BALLET", "BURLESQUE"]
}

Eu tentei cadastrar como consta acima, mas recebo este erro:

"trace": "org.springframework.web.bind.MethodArgumentNotValidException: Validation failed for argument [0] in public void burlesca.escola.api.controller.ProfessoraController.cadastrar(burlesca.escola.api.professoras.ProfessoraDTO): [Field error in object 'professoraDTO' on field 'modalidades': rejected value [null];

Tem que ser o mesmo nome do atributo do Record, pois o record deve ser um espelho do JSON

Está igual, mas ainda assim não roda... meu record está assim:

public record ProfessoraDTO(
        @NotBlank
        String nome,
        @NotBlank @Email
        String email,
        @NotBlank
        String telefone,
        @NotNull
        List<Modalidade> modalidades){}

Eu faço o envio dos dados:

{
    "nome": "Marta Rocha",
    "email":"marta@escolaburlesca.com",
    "telefone": "1189999977",
    "modalidades": ["BALLET", "BURLESQUE"]
}

E recebo esse erro, que diz ser na minha classe Controller:

"org.springframework.web.bind.MethodArgumentNotValidException: Validation failed for argument [0] in public void burlesca.escola.api.controller.ProfessoraController.cadastrar(burlesca.escola.api.professoras.ProfessoraDTO): [Field error in object 'professoraDTO' on field 'modalidade': rejected value [null];

Minha classe controller está assim:

@RestController
@RequestMapping("/professoras")

public class ProfessoraController {

    @Autowired
    private ProfessoraRepository repository;

    @PostMapping
    @Transactional
    public void cadastrar(@RequestBody @Valid ProfessoraDTO dados){
        repository.save(new Professora(dados));
    }
}
solução!

Agora está tudo certo.

Mas estranho que na mensagem que erro que você mandou: Field error in object 'professoraDTO' on field 'modalidade': rejected value [null];

Está dizendo que o atributo no ProfessoraDTO se chama modalidade (no singular). Pode ser que o projeto não tenha reiniciado e pegado as mudanças no código automaticamente. Pare o projeto e rode novamente para testar.

Reiniciei e agora foi :D

Muuuuito obrigada!