Relaciones de tabla versus relaciones de entidad
En un sistema de base de datos relacional, solo puede haber tres tipos de relaciones de tabla:
- uno a muchos (a través de una columna de clave externa)
- uno a uno (a través de una clave primaria compartida)
- muchos a muchos (a través de una tabla de enlaces con dos claves externas que hacen referencia a dos tablas principales separadas)
Entonces, una one-to-many
relación de tabla tiene el siguiente aspecto:
Tenga en cuenta que la relación se basa en la columna Clave externa (por ejemplo, post_id
) en la tabla secundaria.
Entonces, hay una sola fuente de verdad cuando se trata de administrar una one-to-many
relación de tabla.
Ahora, si toma una relación de entidad bidireccional que se asigna en la one-to-many
relación de tabla que vimos anteriormente:
Si observa el diagrama anterior, puede ver que hay dos formas de gestionar esta relación.
En la Post
entidad, tiene la comments
colección:
@OneToMany(
mappedBy = "post",
cascade = CascadeType.ALL,
orphanRemoval = true
)
private List<PostComment> comments = new ArrayList<>();
Y, en el PostComment
, la post
asociación se asigna de la siguiente manera:
@ManyToOne(
fetch = FetchType.LAZY
)
@JoinColumn(name = "post_id")
private Post post;
Entonces, tiene dos lados que pueden cambiar la asociación de la entidad:
- Al agregar una entrada en la
comments
colección secundaria, se post_comment
debe asociar una nueva fila con la post
entidad principal a través de supost_id
columna.
- Al establecer la
post
propiedad de la PostComment
entidad, la post_id
columna también debe actualizarse.
Debido a que hay dos formas de representar la columna Clave externa, debe definir cuál es la fuente de la verdad cuando se trata de traducir el cambio de estado de asociación en su modificación de valor de columna de clave externa equivalente.
MappedBy (también conocido como el lado inverso)
El mappedBy
atributo indica que el @ManyToOne
lado está a cargo de administrar la columna Clave externa, y que la colección se usa solo para recuperar las entidades secundarias y en cascada los cambios de estado de la entidad primaria a los elementos secundarios (por ejemplo, eliminar el elemento primario también debería eliminar las entidades secundarias).
Se llama el lado inverso porque hace referencia a la propiedad de entidad secundaria que administra esta relación de tabla.
Sincronice ambos lados de una asociación bidireccional
Ahora, incluso si definió el mappedBy
atributo y la @ManyToOne
asociación del lado secundario maneja la columna Clave externa, aún necesita sincronizar ambos lados de la asociación bidireccional.
La mejor manera de hacerlo es agregar estos dos métodos de utilidad:
public void addComment(PostComment comment) {
comments.add(comment);
comment.setPost(this);
}
public void removeComment(PostComment comment) {
comments.remove(comment);
comment.setPost(null);
}
Los métodos addComment
y removeComment
aseguran que ambos lados estén sincronizados. Entonces, si agregamos una entidad secundaria, la entidad secundaria debe apuntar al elemento primario y la entidad principal debe tener el elemento secundario contenido en la colección secundaria.
Para obtener más detalles sobre la mejor manera de sincronizar todos los tipos de asociación de entidades bidireccionales, consulte este artículo .