Il Service Builder fornito con Liferay è uno strumento molto potente per generare la maggior parte dello strato di persistenza necessario alle nostre portlet.
Purtroppo però l'unica documentazione ufficiale disponibile è rappresentata dai commenti contenuti all'interno del DTD del file service.xml; utile ma non sempre esaustiva.
Cerchiamo quindi di capire come preparare opportunamente il file service.xml per mappare una relazione molti-a-molti (many-to-many relationship).
Poniamoci quindi nella situazione in cui dobbiamo mappare una relazione tra autori e libri:
- un autore può scrivere più libri
- un libro può avere più autori
A livello di struttura di database sappiamo bene come mappare questa relazione:
- una tabella per gli autori
- una tabella per i libri
- una tabella di join che collega autori e libri
La prima entity da creare è quella dell'autore:
<entity name="Autore" local-service="true">
<column name="autoreId" type="long" primary="true" />
<column name="nominativo" type="String" />
<!-- Seguono altre colonne, finder, ... -->
</entity>
Poi definiamo la entity del libro:
<entity name="Libro" local-service="true">
<column name="libroId" type="long" primary="true" />
<column name="titolo" type="String" />
<!-- Seguono altre colonne, finder, ... -->
</entity>
Infine definiamo la entity di join:
<entity name="Autore_Libro" local-service="true">
<column name="autoreId" type="long" primary="true" />
<column name="libroId" type="long" primary="true" />
</entity>
Quanto visto sopra sarebbe già sufficiente per un normale funzionamento; tuttavia sarebbe molto comodo avere out-of-the-box funzionalità del tipo: dammi tutti i libri di un autore, dammi tutti gli autori del libro.
Fortunatamente il service builder viene in nostro aiuto.
All'interno della entity Autore, andiamo ad aggiungere la seguente colonna:
<column name="libri" type="Collection" entity="Libro" mapping-table="Autore_Libro" />
Allo stesso modo aggiungiamo la seguente colonna alla entity Libro:
<column name="autori" type="Collection" entity="Autore" mapping-table="Autore_Libro" />
E' importante ricordare che, in caso di relazione many-to-many, occorre specificare la colonna di join su entrambe le entity.
Finito. Ora è possibile lanciare lo script Ant build-service e verranno così creati i metodi di persistenza per la gestione del join, nelle rispettive classi di Autore e Libro:
p
ublic List<Libro> getLibros(long autoreId) throws SystemException;
public List<Autore> getAutores(long libroId) throws SystemException;
Enjoy!