Como esta es una pregunta muy común, escribí
este artículo , en el que se basa esta respuesta.
Asociación unidireccional de uno a muchos
Como expliqué en este artículo , si usa la @OneToMany
anotación con @JoinColumn
, entonces tiene una asociación unidireccional, como la que existe entre la Post
entidad principal y el elemento secundario PostComment
en el siguiente diagrama:
Cuando se usa una asociación unidireccional de uno a muchos, solo el lado padre mapea la asociación.
En este ejemplo, solo la Post
entidad definirá una @OneToMany
asociación con la PostComment
entidad secundaria :
@OneToMany(cascade = CascadeType.ALL, orphanRemoval = true)
@JoinColumn(name = "post_id")
private List<PostComment> comments = new ArrayList<>();
Asociación bidireccional uno a muchos
Si usa el @OneToMany
con el mappedBy
conjunto de atributos, tiene una asociación bidireccional. En nuestro caso, tanto la Post
entidad tiene una colección de PostComment
entidades secundarias como la PostComment
entidad secundaria tiene una referencia a la Post
entidad principal , como se ilustra en el siguiente diagrama:
En la PostComment
entidad, la post
propiedad de la entidad se asigna de la siguiente manera:
@ManyToOne(fetch = FetchType.LAZY)
private Post post;
La razón por la que establece explícitamente la fetch
atributo a FetchType.LAZY
se debe a que, por defecto, todos @ManyToOne
y @OneToOne
asociaciones se recuperan con impaciencia, que puede causar N + 1 temas de consulta. Para obtener más detalles sobre este tema, consulte este artículo .
En la Post
entidad, la comments
asociación se asigna de la siguiente manera:
@OneToMany(
mappedBy = "post",
cascade = CascadeType.ALL,
orphanRemoval = true
)
private List<PostComment> comments = new ArrayList<>();
El mappedBy
atributo de la @OneToMany
anotación hace referencia a la post
propiedad en la PostComment
entidad secundaria y, de esta manera, Hibernate sabe que la asociación bidireccional está controlada por el @ManyToOne
lado, que se encarga de administrar el valor de la columna Clave externa en la que se basa esta relación de tabla.
Para una asociación bidireccional, también debe tener dos métodos de utilidad, como addChild
y removeChild
:
public void addComment(PostComment comment) {
comments.add(comment);
comment.setPost(this);
}
public void removeComment(PostComment comment) {
comments.remove(comment);
comment.setPost(null);
}
Estos dos métodos aseguran que ambos lados de la asociación bidireccional no estén sincronizados. Sin sincronizar ambos extremos, Hibernate no garantiza que los cambios de estado de asociación se propaguen a la base de datos.
Para obtener más detalles sobre el mejor wat para sincronizar asociaciones bidireccionales con JPA e Hibernate, consulte este artículo .
¿Cuál elegir?
La asociación unidireccional @OneToMany
no funciona muy bien , por lo que debe evitarla.
Es mejor usar el bidireccional, @OneToMany
que es más eficiente .