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

Dúvida ao setar o campo serie em SetEpisodios

Bom dia!

Olha, eu faço a formação desde o início, passando pela Orientação a Objetos e não me lembro desse conhecimento passando como parâmetro o "this".

public void setEpisodios(List<Episodio> episodios) {
        episodios.forEach(e -> e.setSerie(this));
        this.episodios = episodios;
    }

O que eu sabia, até então é que o "this" servia para identificar o atributo da classe, por exemplo: this.atributo1, this.atributo2...

Dar forma como foi colocado na aula, eu não me recordo de ter aprendido (posso ter "comido bola"), então gostaria de entender como isso funciona.

Como que o "this" passado entre parênteses consegue associar o atributo "id" da Serie para o setSerie?

Obrigado.

6 respostas

Oi de novo, Sergio! hahaha

Na verdade, o this é um ponteiro, um apontador para o próprio objeto. Como assim?

Sempre utilizamos o this dentro de uma classe, certo? Pense que existem classes, mas dentro de uma classe específica, podemos ter vários objetos e fazer várias coisas com esses objetos. Mas e se quisermos trabalhar com a própria classe, fazer algo com um objeto específico daquele tipo? Por exemplo, dando valor aos atributos do objeto. Precisamos indicar isso para o compilador de alguma forma, que no caso é utilizar o this.

No exemplo de código da aula, queremos setar a série do episodio, mas estamos justamente na nossa classe Serie, então queremos passar aquele objeto específico do tipo série para o nosso episódio. Portanto, novamente utilizamos o this. Assim, o atributo serie do episódio será essa série, o this.

Temos a classe, que é um modelo geral de séries, e o objeto, que é uma instância específica de série. Se estamos nos referindo ao objeto em si (que é algo mais "exclusivo"), usamos o this.

A parte do id que você mencionou já é outra coisa, relacionada à JPA. Então terminamos de setar a série do episódio, e o relacionamento está corretamente configurado. Assim, a JPA irá converter o relacionamento entre objetos para tabelas e colunas, fazendo com que o id apareça corretamente.

O entendimento dessa parte de ponteiros trabalha com a memória em um nível mais baixo, então é mais complicado mesmo. Espero ter esclarecido e qualquer dúvida, estou à disposição!

Olá Iasmin!

Vamos ver se eu entendi.

Na classe Serie, estamos passando o objeto da Serie (this) para o campo serie de da classe Episodio, que na tabela é serie_id.


    public void setEpisodios(List<Episodio> episodios) {
        episodios.forEach(e -> e.setSerie(this));
        this.episodios = episodios;
    }

O que eu ainda não compreendi bem é como que o campo serie (serie_id) conseguiu essa atribuição 1, 2 ou 3 que equivale à propriedade id da Serie ?

Quando você diz setar a serie do Episodio, eu só visualizei o número do id da Serie ao qual se refere o Episodio. É essa "mágica" que eu ainda não estou conseguindo compreender.

Ou seja, se eu passo o objeto (this) da Serie para e.setSerie(this), como, do outro lado, a classe Episodio entende que para o campo serie deve pegar o id da Serie? Está pegando id, não está?

Boa noite, Sérgio!

Então, existem duas coisas que estão conectadas aqui: a aplicação Java do screenmatch e o banco de dados do screenmatch. Cada um deles tem um jeito de representar os dados. No caso da aplicação, temos as classes e objetos. Quando eu digo que setei a serie de um episódio, quero dizer que, pra cada episódio da lista episodios (que é um campo da classe Serie), eu fiz com que o campo serie do meu episódio passasse a apontar para a série da classe (this). Então lá na memória do computador, houve essa mudança.

Na nossa aplicação, estamos lidando com objetos. Então o objeto do tipo série "Game of Thrones" tem como atributo uma lista de objetos, que são episódios. Por sua vez, dentro de cada episódio também tem um campo serie. Então o episódio "Battle of bastards" faz parte dessa lista, mas esse episódio tem uma série associada, que é "Game of Thrones". Quando chamamos o set, estamos justamente falando pra qual série o episódio irá apontar lá na memória.

Quando utilizamos a JPA, juntamente ao Hibernate, queremos transformar essa parte da aplicação em tabelas. Só que na tabela eu não posso "guardar" um objeto inteiro, não posso trabalhar com essa lógica de apontar. Eu não guardo um episódio em uma série, nem o contrário. Por definição mesmo, as relações são feitas por id.

Por baixo dos panos, com todas as anotações e os atributos que configuramos, a JPA vai entender que cada episódio está associado a uma série. Daí, para falar a qual série o episódio está associado, ela pega o id do objeto série, cria um campo serie_id e guarda esse campo, além de também indicar que serie_id é uma chave estrangeira. Assim, toda vez que precisarmos identificar essa relação, iremos utilizar esses recursos de relacionamentos e chaves estrangeiras no banco. Esse é o mapeamento entre banco de dados e aplicação.

Voltando ao exemplo do Game of Thrones: os objetos da aplicação estão devidamente conectados, mas precisamos passar isso para o banco de dados. Como cadastramos episódios somente depois de cadastrar a série, o episódio já "nasce" com uma série associada. E aí, se na memória o "Battle of Bastards" aponta para Game of Thrones, quando a JPA transforma isso em tabelas, ela olha para o objeto "Game of thrones', verifica que ele tem id 2, por exemplo, e muda o campo serie_id para 2.

Espero que tenha ficado mais claro!

Olá Iasmin, obrigado novamente pelos detalhes da explicação!

Então é uma transformação que ocorre de acordo com as nossas configurações, quando consegue pegar o id da Serie e colocar no campo serie_id.

Posso presumir então, que se não houvesse o atributo id da Serie esse relacionamento não funcionaria.

O id é a chave primária de Serie e serie_id é a chave estrangeira de Episodio, mas, hipoteticamente se eu eliminasse esse id dos atributos de Serie e considerasse por exemplo o atributo titulo como chave primária (mesmo sabendo que pelas boas práticas não seria uma boa ideia), o campo serie de Episodios assumiria o nome do titulo para essa relação de chave estrangeira?

Ou seja, seria possível trocar o id (chave primária) por qualquer outro campo assumindo ser chave primária e o relacionamento entre as 2 tabelas continuaria a funcionar nessa relação? O campo serie (no banco) conseguiria assumir o novo valor?

solução!

Boa tarde, Sérgio!

Na verdade, se a série não tivesse nenhum atributo anotado com um @Id, ela não poderia nem ser uma entidade do banco de dados, porque essa é uma anotação obrigatória do mapeamento com Hibernate/JPA. Mas repare que estou falando da anotação em si. Poderíamos não ter o campo id, e mapear o título, por exemplo, como o id da entidade, sendo ele a chave primária. Dessa forma, funcionaria também, exatamente da forma que você perguntou: o episódio teria uma chave estrangeira que iria corresponder ao título. Portanto, o @Id serve pra indicar que aquele campo é a chave primária da entidade.

Agora, falando do banco de dados em si (esquecendo a parte de Java e JPA), até poderíamos ter uma tabela serie sem uma chave primária, mas seria impossível ter o relacionamento entre série e episódio, uma vez que o relacionamento pega a chave primária de uma entidade e a transforma em uma chave estrangeira na outra tabela. Porém, como estamos trabalhando com a JPA, ela já nos obriga a configurar a chave primária com o @Id na classe, então não passamos por esse problema.

Aqui, cabe só mais uma informação: se a série não tivesse um atributo id, não necessariamente o relacionamento daria errado: o necessário mesmo é que ela tenha uma chave primária, que pode ou não ser o id.

Clareou bastante agora! Muito obrigado!