Relacionamentos de tabela vs. relacionamentos de entidade
Em um sistema de banco de dados relacional, pode haver apenas três tipos de relacionamentos de tabela:
- um para muitos (por meio de uma coluna Chave estrangeira)
- individual (por meio de uma chave primária compartilhada)
- muitos-para-muitos (através de uma tabela de links com duas chaves estrangeiras referenciando duas tabelas pai separadas)
Portanto, um one-to-manyrelacionamento de tabela é o seguinte:

Observe que o relacionamento é baseado na coluna Chave estrangeira (por exemplo, post_id) na tabela filha.
Portanto, existe uma única fonte de verdade quando se trata de gerenciar um one-to-manyrelacionamento de tabela.
Agora, se você usar um relacionamento de entidade bidirecional que mapeie o one-to-manyrelacionamento de tabela que vimos anteriormente:

Se você der uma olhada no diagrama acima, poderá ver que existem duas maneiras de gerenciar esse relacionamento.
Na Postentidade, você tem a commentscoleção:
@OneToMany(
mappedBy = "post",
cascade = CascadeType.ALL,
orphanRemoval = true
)
private List<PostComment> comments = new ArrayList<>();
E, no PostComment, a postassociação é mapeada da seguinte maneira:
@ManyToOne(
fetch = FetchType.LAZY
)
@JoinColumn(name = "post_id")
private Post post;
Portanto, você tem dois lados que podem alterar a associação da entidade:
- Ao adicionar uma entrada na
commentscoleção filha, uma nova post_commentlinha deve ser associada à postentidade pai por meio de sua post_idcoluna.
- Ao definir a
postpropriedade da PostCommententidade, a post_idcoluna também deve ser atualizada.
Como existem duas maneiras de representar a coluna Chave Externa, você deve definir qual é a fonte da verdade quando se trata de converter a alteração do estado da associação em sua modificação equivalente no valor da coluna Chave Externa.
MappedBy (também conhecido como lado inverso)
O mappedByatributo informa que o @ManyToOnelado é responsável pelo gerenciamento da coluna Chave Externa, e a coleção é usada apenas para buscar as entidades filhas e fazer cascata de alterações no estado da entidade pai para filhos (por exemplo, remover o pai também deve remover as entidades filho).
É chamado de lado inverso porque faz referência à propriedade da entidade filha que gerencia esse relacionamento de tabela.
Sincronize os dois lados de uma associação bidirecional
Agora, mesmo se você definiu o mappedByatributo e a @ManyToOneassociação do lado filho gerencia a coluna Chave Externa, ainda é necessário sincronizar os dois lados da associação bidirecional.
A melhor maneira de fazer isso é adicionar esses dois métodos utilitários:
public void addComment(PostComment comment) {
comments.add(comment);
comment.setPost(this);
}
public void removeComment(PostComment comment) {
comments.remove(comment);
comment.setPost(null);
}
Os métodos addCommente removeCommentgarantem que ambos os lados estejam sincronizados. Portanto, se adicionarmos uma entidade filha, a entidade filha precisará apontar para o pai e a entidade pai deverá ter o filho contido na coleção filho.
Para obter mais detalhes sobre a melhor maneira de sincronizar todos os tipos de associação de entidade bidirecional, consulte este artigo .