## INTEGRAZIONE TRA DATAGEN E SERVICEGEN tramite Spring

Uno scenario molto diffuso delle applicazioni J2EE generate tramite i tools MDD Servicegen e Datagen può essere quello di avere un servizio applicativo generato con servicegen che utilizzi per la realizzazione della business logic uno strato di accesso ai dati (DAO) generato con datagen. Tipicamente per realizzare questo tipo di design implementativo è necessario integrare le funzionalità dei due generatori: l'integrazione avviene tramite spring.

Nell design del codice generato dai due tools entrano in gioco i seguenti elementi:

- elementi forniti da servicegen
  - bean di implementazione del servizio: è un bean generato che possiede un metodo per ogni Operation definita nell' interfaccia di servizio; lo sviluppatore ha il compito di inserire manualmente per ogni metodo/operazione la logica di business.
  - uno o più bean (opzionali) con il ruolo di manager, totalmente scritti a mano, che permettono di strutturare al meglio la logica di business (ad esempio per mettere a fattor comune sotto-funzionalità utilizzate in più di una operazione)
- elementi forniti da datagen
  - un bean per ogni DataAccessObject: effettua l'accesso al DBMS

I tipici modi per combinare questi elementi (e quindi per integrare i due strumenti) sono quelli descritti nel seguente esempio.

- il bean di implementazione effettua l'accesso alla base dati utilizzando direttamente un dao (nell'esempio: Dao1)
- il bean di implementazione non accede direttamente al dao ma colloquia con il bean manager, il quale a sua volta coordina i vari dao e delega ad essi l'accesso vero e proprio ai dati.

Per ottenere questo design integrato è necessario operare su vari fronti:

- modellazione di servicegen in modo da utilizzare spring
- definizione (manuale) degli eventuali bean manager
- configurazione dei file di contesto di spring in modo da combinare i vari bean

### Passo 1: modellazione del servizio applicativo con opzione di utilizzo di spring

Supponiamo di voler creare un servizio applicativo.
Dopo aver definito nel ServiceDef le operazioni offerte dal servizio, è necessario definire nel modello principale (quello con root-element di tipo SOABEModel) l'implementazione, attraverso l'elemento ServiceImpl. Scegliamo come cartridge l'elemento ManualImplCartridge (che sta ad indicare che l'implementazione dei metodi dovrà essere realizzata tramite codifica manuale) e impostiamo la property useInjectedPojo a true: tale opzione permette di generare tutti i files necessari per utilizzare spring. In particolare per lo sviluppatore è rilevante (perchè dovrà integrarlo con configurazioni aggiuntive) il file di configurazione del contesto spring, che conterrà:

- la configurazione del bean di implementazione, comprensivo di regione protetta utilizzabile per la configurazione di collegamenti tra questo bean e gli altri bean (dao, manager)
- una regione protetta dove sarà possibile configurare gli eventuali bean manager

Il seguente esempio (fig.1) mostra un modello Servicegen in cui viene dichiarato un servizio applicativo con una sola operazione, `sayHello()`.

Il file di configurazione di spring (da integrare manualmente) viene generato nella seguente posizione: `{progetto}/conf/ejb/{servizio}/META-INF/{servizio}BeanContext.xml`, esempio: `hello.mdd/conf/ejb/hello/META-INF/helloBeanContext.xml`

Il generatore crea anche un altro file di configurazione di spring, destinato a contenere i bean dello strato di accesso ai dati. Tale file è generato nella seguente posizione: `{progetto}/conf/ejb/{servizio}/META-INF/{servizio}Dao-beans.xml`, esempio: `hello.mdd/conf/ejb/hello/META-INF/helloDao-beans.xml` ed è caricato allo startup del contesto spring.

Nella modalità non integrata servicegen-datagen è necessario inserire manualmente le configurazioni dei dao in questo file; nella modalità integrata invece occorre fare in modo che questo file sia generato da datagen invece che da servicegen, e fare in modo che datagen lo generi nella stessa posizione dove se lo aspettano le classi di startup di spring. Per fare ciò è necessario agire a livello di workflow di generazione:

- nel richiamo della cartuccia di generazione di servicegen occorre utilizzare il parametro `useExternalDaoBeans` valorizzato a true: in questo modo servicegen non genererà il file.
- nel richiamo della cartuccia di generazione di datagen occorre utilizzare il parametro `daoBeansFileName` (nell'esempio precedente il valore di questo parametro dovrà essere ad esempio: `hello.mdd/conf/ejb/hello/META-INF/helloDao-beans.xml`).

N.B:è importante che siano effettuate entrambe le configurazioni altrimenti i due generatori sovrascriverebbero l'uno con l'altro il file con effetti dannosi indesiderati (es. perdita del contenuto delle regioni protette o perdita della definizione dei bean DAO, a seconda che sia eseguito prima l'uno o l'altro generatore).

### Passo 2: modellazione dello strato di accesso ai dati

Nella fig. 2 è esemplificato un modello datagen che descrive un ipotetico strato di accesso ai dati:

Non sono necessari particolari accorgimenti su tale modello per permettere l'integrazione in servicegen. E' invece necessario apportare alcune impostazioni sul file di workflow, al momento del richiamo della cartuccia datagen. Oltre all'impostazione del percorso in cui dovrà essere creato il file xml (vedere sopra) è anche necessario fare in modo che le classi java generate da datagen vengano collocate nella corretta alberatura di package. Trattandosi di un servizio la corretta alberatura per lo strato di accesso ai dati à all'interno del package `business.`. L'impostazione del package-base viene effettuata con un apposito parametro della cartuccia di generazone di datagen: `basePackage`. Ad esempio, se il componente java del servizio ha codice prodotto `testprod` e codice componente `testcomp`, occorrerà utilizzare la seguente impostazione di tale parametro: `it.csi.testprod.testcomp`, in questo modo i DAO verranno generati nel package: `it.csi.testprod.testcomp.business.dao`.
Completata la generazione inserire nella regione protetta del Dao-beans.xml i riferimenti al dataSource

### Passo 3 (opz.): definizione del bean manager

Nel caso risulti utile definire uno o più bean custom con il ruolo di manager, questi possono essere definiti come normali bean di Spring (POJO) e conterranno tipicamente i metodi necessari per implementare la specifica business logic. Ciascuno di tali bean, al fine di implementare il design descritto in fig.1, referenzia (ovvero utilizza operativamente nella sua classe) i bean dei dao generati con Datagen. Ovviamente è possibile anche che il bean custom abbia referenze ad eventuali altri bean definiti manualmente dall'utente.

### Passo 4: costruzione delle dipendenze spring

Il collante tra bean di implementazione, manager, dao è spring. Per costruire la struttura descritta in fig. 1 è necessario:

- definire nel bean di implementazione le property destinate a contenere i riferimenti ai bean manager e dao
- definire nei bean manager le property destinate a contenere i riferimenti ai bean dao necessari
- completare i file di configurazione di spring in modo da costruire il grafo di dipendenze tra i vari bean.

### Passo 5: Gestione transazione sui dati

Per gestire le transazioni sui dati è necessario rendere transazionale l' Operation definito sul modello ServiceDef (impostare la property Tx Type a NewLocalTx). Per garantire la Rollback dei datile vie sono due:

- rilanciare (throw) un'eccezione unchecked (es. RuntimeException)
- invocare session.setRollBackOnly()

[http://kbt.csi.it/sviluppo/problematiche-ricorrenti/item/683-come-si-gestisce-il-rollback-delle-transazioni-quando-si-usa-spring]