Poiché questa è una domanda molto comune, ho scritto
questo articolo , su cui si basa questa risposta.
Associazione one-to-many unidirezionale
Come ho spiegato in questo articolo , se usi l' @OneToMany
annotazione con @JoinColumn
, allora hai un'associazione unidirezionale, come quella tra l' Post
entità genitore e il figlio PostComment
nel diagramma seguente:
Quando si utilizza un'associazione uno-a-molti unidirezionale, solo la parte padre mappa l'associazione.
In questo esempio, solo l' Post
entità definirà @OneToMany
un'associazione PostComment
all'entità figlio :
@OneToMany(cascade = CascadeType.ALL, orphanRemoval = true)
@JoinColumn(name = "post_id")
private List<PostComment> comments = new ArrayList<>();
Associazione uno-a-molti bidirezionale
Se si utilizza il set @OneToMany
con l' mappedBy
attributo, si dispone di un'associazione bidirezionale. Nel nostro caso, sia l' Post
entità ha una raccolta di PostComment
entità figlio, sia l' PostComment
entità figlio ha un riferimento Post
all'entità madre , come illustrato dal diagramma seguente:
Nella PostComment
entità, la post
struttura entità viene mappato come segue:
@ManyToOne(fetch = FetchType.LAZY)
private Post post;
Il motivo per cui abbiamo impostato esplicitamente l' fetch
attributo FetchType.LAZY
è perché, per impostazione predefinita, tutte @ManyToOne
e le @OneToOne
associazioni vengono recuperate con impazienza, il che può causare problemi di query N + 1. Per maggiori dettagli su questo argomento, consulta questo articolo .
Nella Post
entità, l' comments
associazione viene mappato come segue:
@OneToMany(
mappedBy = "post",
cascade = CascadeType.ALL,
orphanRemoval = true
)
private List<PostComment> comments = new ArrayList<>();
L' mappedBy
attributo @OneToMany
dell'annotazione fa riferimento alla post
proprietà PostComment
nell'entità figlio e, in questo modo, Hibernate sa che l'associazione bidirezionale è controllata dal @ManyToOne
lato, che è responsabile della gestione del valore della colonna Chiave esterna su cui si basa questa relazione di tabella.
Per un'associazione bidirezionale, è inoltre necessario disporre di due metodi di utilità, come addChild
e removeChild
:
public void addComment(PostComment comment) {
comments.add(comment);
comment.setPost(this);
}
public void removeComment(PostComment comment) {
comments.remove(comment);
comment.setPost(null);
}
Questi due metodi garantiscono che entrambe le parti dell'associazione bidirezionale non siano sincronizzate. Senza sincronizzare entrambe le estremità, Hibernate non garantisce che le modifiche allo stato dell'associazione si propagheranno al database.
Per maggiori dettagli sul miglior wat per sincronizzare le associazioni bidirezionali con JPA e Hibernate, consulta questo articolo .
Quale scegliere?
L' associazione unidirezionale @OneToMany
non funziona molto bene , quindi dovresti evitarlo.
Stai meglio usando il bidirezionale @OneToMany
che è più efficiente .