4
respostas

Ajuda no relacionamento de entidades

Opa pessoal beleza? me encontrei em uma situação e estou com algumas duvidas, se puderem me dar um norte... vamos lá!

Tenho uma classe Person porem, preciso separar já pensando no formulário da aplicação web, pessoa jurídica e física.

Tenho uma classe também que se chama Post, e ela precisa ter um Person e o Person tem uma Lista de Post.

Show!

Eu estou na duvida é na estrategia, em como vou salvar esse Client.

Fiz assim:

Classe Person

@Data
@Entity
@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
public abstract class Person {

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

    @Column(name = "logo")
    private String imageUrl;

    @Column(name = "contato")
    private String contact;

Fiz uma Herança: PersonLegal

@EqualsAndHashCode(callSuper = true)
@Data

@Entity
public class PersonLegal extends Person {

    @Column(name = "razao_social")
    private String socialReason;

Classe PersonPhysical

@EqualsAndHashCode(callSuper = true)
@Data

@Entity
public class PersonPhysical extends Person {

    private String name;

    @Column(length = 11)
    private String cpf;

Reparem que utilizei essa anotação na classe pai person:

@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)

Pelo que pesquisei, apenas as classes concretas serão geradas, ou seja as filhas, mas acho que o id delas podem ser igual.

Agora no meu Post, eu preciso colocar um Person lá, que ele possui

Post:

    ManyToOne
    @JoinColumn(name = "person_id")
    private Person person;

E no Person eu tenho uma lista de Post

 @JsonIgnore
    @OneToMany(mappedBy = "person", fetch = FetchType.LAZY)
    private List<Post> posts;

Perguntas:

1 - Essa estrategia de ele criar apenas as classes filhas é o recomendado nesse caso?

2 - Esta dando erro na minha classe Post, quando coloco o Person lá erro:

'Basic' attribute type should not be 'Persistence Entity' 

3 - Quando eu salvar um um Person, como vai ser a minha Repository? Eu vou ter que criar um repository para as filhas e tambem para o pai?

To bem confuso, se puderem ajudar, vai me salvar

Abraços

4 respostas

Oi Daniel, sua dúvida na verdade está mais relacionada ao mapeamento de herança utilizando JPA.

As três estratégias(SINGLE_TABLE, JOINED e TABLE_PER_CLASS) tem vantagens e desvantagens, devendo você avaliar qual delas é mais apropriada para o seu cenário.

No seu caso acho que a estratégia que você escolheu vai funcionar sem muitos problemas.

A ideia então é você ter um repository para cada classe filha, para trabalhar com as entidades de maneira separada.

O erro que você citou pode ser algum problema no mapeamento da sua classe Post. Pode postar o código completo dela aqui?

Opa professor, massa! Entendi, então essa estrategia pode servir, eu vou dar uma analisada melhor.

Para esse cenário então eu tenho que ter o Repository das filhas separadas, ok, isso eu sakei!!

Mas e a classe pai? Ela só me serve de modelo para as outras?

Por que no meu relacionamento, qual é a ideia:

Uma Pessoa, independente se for fisica ou juridica, tem uma lista de Postos.

Segue as classes

@Data

@Entity
public class Post {

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

    @Column(name = "nome")
    private String name;

    private String imageUrl;

    @OneToOne
    private Gasoline gasoline;

    @OneToOne
    private Diesel diesel;

    @OneToOne
    private Ethanol ethanol;

    @OneToOne
    private GasolineAdditive gasolineAdditive;

    @OneToOne
    private Alcohol alcohol;

    @OneToOne
    private Gnv gnv;

    @ManyToOne
    @JoinColumn(name = "person_id")
    private Person person;

    @Column(name = "data_criacao_posto")
    private LocalDate postDate;

    @OneToOne(cascade = CascadeType.ALL)
    @JoinColumn(name = "endereco_posto_id")
    private Address address;

Person:

@Data
@Entity
@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
public abstract class Person {

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

    @Column(name = "logo")
    private String imageUrl;

    @Column(name = "contato")
    private String contact;

    @OneToOne(cascade = CascadeType.ALL)
    @JoinColumn(name = "endereco_person_id")
    private Address address;

    @ManyToOne(cascade = CascadeType.ALL)
    private User user;

    @Column(name = "data_criacao_pessoa")
    private LocalDate personDate;

    @JsonIgnore
    @OneToMany(mappedBy = "person", fetch = FetchType.LAZY)
    private List<Post> posts;

Abrindo o projeto hoje, o erro parou! kk vai entender

Mas acho que o relacionamento esta correto instrutor.

O que pega agora, é quando eu for fazer o DTO de Person Como que vou sera no back end, qual instancia vou ter que criar na hora de salvar, como vou saber se é pessoa jurídica ou física...

No metodo PersonImplementation por exemplo:

@Service
@RequiredArgsConstructor
public class PersonImplementation implements PersonService {

    private final PersonPhysicalRepository personPhysicalRepository;
    private final PersonLegalRepository personLegalRepository;
    private final AddressRepository addressRepository;

    @Override
    public Person save(PersonDto personDto) {



        return null;
    }
}

Aqui que esta a duvida rsrs

Acredito que no seu projeto esse cadastro será separado, tendo uma tela para cada tipo de pessoa, certo?

Então eu criaria as classes separadas, para não dar confusão.

Tipo, 1 DTO, 1 Service e 1 Controller separado para cada tipo de pessoa, utilizando herança entre eles quando fizer sentido, para não ter muito código repetido.

Massa instrutor To com a mão no código aqui, o que pensei em fazer é isso mesmo.

Um DTO para pessoa física, um para pessoa jurídica, controller e service também para cada uma das suas separadas.

Lá na frente no meu front end eu abro um formulário diferente para cada um dos tipos de pessoa. eu vou ter que escolher, pessoa física ou jurídica. ai eu pego a rota digamos assim de acordo com o que foi escolhido.

Acho que a herança aqui é mais para diferencia os atributos opostos um do outro como o CNPJ e o CPF mas também pegando dados comuns que eles vão ter, endereço, logo e afins.

Brigadão professor, abraços

Quer mergulhar em tecnologia e aprendizagem?

Receba a newsletter que o nosso CEO escreve pessoalmente, com insights do mercado de trabalho, ciência e desenvolvimento de software