lunedì 4 agosto 2014

L'auto-referenziazione in Hibernate

Vai all'indice

Un breve accenno merita la gestione dell'autoreferenziazione in Hibernate in particolare relazioni: uno-a-molti e molti-a-molti.
Una tabella è autoreferenziata quando è correlata a se stessa da due campi diversi. Utilizzando  un esempio specifico, sempre la tabella Utente (pensiamo agli utenti come impiegati di un ufficio) può includere l'ID di un manager responsabile di altri utenti nella stessa tabella. Questa relazione è definita self-join o self-reference che è una sorta di struttura padre/figlio.


L'auto-referenziazione in Hibernate

Nella tabella Utente, è necessario definire una colonna MANAGER_ID mappata nella tabella stessa. Così per ogni dipendente verrà memorizzato id del proprio responsabile.

   ...
    @ManyToOne(cascade={CascadeType.ALL})
    @JoinColumn(name="manager_id")
    private Utente manager;

    @OneToMany(mappedBy="manager")
    private Set<Utente> subord = new HashSet<Utente>();
   ...

Nell'entità Utente sono state definiti due nuovi attributi: manager e subord che è un Set <Utente>. manager viene mappato con l'annotazione @ManyToOne mentre subord con @OneToMany. All'interno di @OneToMany è stato definito mappedBy = "manager" questo rende l'oggetto manager parte proprietaria dell'associazione.

Questa appena descrittà è un'associazione uno-a-molti, ma è possibile definire anche relazioni molti-a-molti autoreferenziate. Basti pensare ad una associazione del tipo utente e colleghi (anch'essi definiti come utenti). In questo caso però è necessario definire una tabella di collegamento come segue.


CREATE TABLE utente_collega (userid int NOT NULL, collid int NOT NULL,  PRIMARY KEY (userid, collid), CONSTRAINT FK_UFF FOREIGN KEY (userid) REFERENCES utente (userid),  CONSTRAINT FK_APP FOREIGN KEY (collid) REFERENCES applicazione (collid);


Nell'entità Utente vanno definite le seguenti annotazioni:

   ...
   @ManyToMany(cascade={CascadeType.ALL})
    @JoinTable(name="utentee_collega",
        joinColumns={@JoinColumn(name="userid")},
        inverseJoinColumns={@JoinColumn(name="collid")})
    private Set<Utente> collx = new HashSet<Utente>();

    @ManyToMany(mappedBy="collx")
    private Set<Utente> utex = new HashSet<Utente>();
   ...

Le annotazioni sono le stesse usate per definire una relazione molti a molti. In questo caso è necessario definire nell'entità Utente sia le annotazione della parte proprietaria che non proprietaria.



Hai apprezzato questo post? Conferma le mie competenze o scrivi una segnalazione sul mio profilo Linkedin!