2012-06-26 11 views
11

Ho una classe dominio padre che ha un hasMany di un'altra classe di dominio. Le classi di dominio padre e figlio hanno entrambi i campi lastUpdated e dateCreated. Il mio problema è che quando aggiorno una classe di dominio figlio, ho bisogno che la classe del dominio genitore rifletta quella modifica e aggiorni anche il suo campo lastUpdated.Aggiornamento del campo "lastUpdated" nella classe Dominio padre in Grails

Esiste qualche mappatura o altra configurazione tra padre e figlio che Grails fornisce che implementerebbe questa funzione?

Aggiornamento

ho aggiunto le seguenti righe alla classe dominio figlio:

def beforeUpdate = { 
    parent.lastUpdated = new Date() 
} 

ho dovuto anche per assicurarsi nel controller che quando ho aggiornato un bambino, ho avuto anche per risparmiare il genitore pure per mantenere il nuovo campo lastUpdated. Questo sembra funzionare bene, ma mi piacerebbe comunque sapere se c'è una mappatura o qualcosa di simile che farebbe questo.

+0

"Nel controllore dovevo anche assicurarmi che, quando aggiornavo un bambino, dovevo salvare anche il genitore" <--- Penso che non sia necessario ... provare a rimuovere il save() su il genitore e guarda se funziona anche senza di esso –

+0

Con Grails 2.2.0, la tecnica di beforeUpdate funziona. Il salvataggio del genitore non è necessario e non avrai alcun doppio comportamento di salvataggio. Quindi non hai bisogno di alcuna formula, solo l'ascoltatore. – Guillaume

risposta

2

Ho la sensazione che la tua implementazione suggerita sia difettosa. Stai aggiornando il impostando manualmente la data lastUpdated, che potrebbe essere perché i grails aggiornino di nuovo lastUpdated dopo averli sporchi controllandoli. In tal caso, verrebbe effettivamente a trovarsi con un'ultima volta che si è verificata dopo la data impostata per l'originale. Nei test, potrebbero essere solo pochi (milli) secondi, ma non è possibile garantirlo.

Non solo, ma la tua implementazione è più difficile da mantenere poiché hai aumentato l'accoppiamento tra Genitore e Bambino.

Potrei suggerire un'altra implementazione? Il campo lastUpdated dovrebbe rappresentare il tempo in cui l'oggetto dominio specifico è stato aggiornato. La data che stai cercando non è esattamente la stessa cosa, quindi non proverei a usare la convenzione esistente nel modo "sbagliato". Sembra che la data desiderata per l'oggetto genitore sia "l'ultima volta che un bambino è stato modificato".

Utilizzare invece una formula.

Per fare ciò, è possibile utilizzare uno formula. Con una formula, ottieni esattamente ciò che vuoi senza dover modificare direttamente l'oggetto genitore, e puoi comunque utilizzare i cercatori dinamici e altri zuccheri Grails.

class Parent { 
    ... 
    Date lastChildUpdated 

    static hasMany = [ children: Child ] 

    static mapping = { 
     ... 
     lastChildUpdated formula: '(SELECT max(c.last_updated) FROM child c WHERE c.parent_id = id)' 
    } 
} 

GORM carica il valore della formula ogni volta che si legge l'oggetto dal database. Ora, ogni volta che salvi un bambino, il genitore avrà un valore preciso per quella proprietà senza dover toccare il genitore.

+0

funziona davvero ?, non ho provato prima o in qualsiasi altro luogo in cui ho visto questo tipo di cose ... !!! – sanghavi7

+0

Scusa, ti ho dato un downvote: la soluzione OP consigliata funziona e il tuo sentimento era sbagliato. E la formula sta apportando molte nuove modifiche: timestamp anche per i bambini, una formula che potrebbe non essere stata chiamata se la tua entità genitore non è stata scaricata e interrogata di nuovo ... – Guillaume

+1

Penso che il sentimento qui sia corretto. Non si dovrebbe veramente modificare l'implementazione di lastUpdated in quanto non si sa davvero quale altro potrebbe dipendere da esso. Penso che questo finisca per essere una soluzione elegante. Tuttavia, penso che ci sia un errore nell'esempio di codice, lo aggiornerò ora. L'esempio non memorizza una colonna aggiuntiva come suggerisce User Guillaume, la colonna è semplicemente come si accederà al valore della formula. –

0

In uno dei miei progetti in cui il dominio era simile. Un programma ha molti AdvertisingMaterial e abbiamo sottoclassi di AdvertisingMaterial, FlashAd, ImageAd ecc. L'utente desidera la possibilità di filtrare i programmi che hanno flashAds, imageAds ecc. Ora ho bisogno di fare il filtro sulla base della proprietà di classe che avere nella tabella del database (quando tabella tablePerHierarchy è true). Così ho apportato alcune modifiche alla mia classe di dominio per ottenere questa proprietà.

class AdvertisingMaterial { 
     String className 

     static constraints = { 
       className(nullable: true) 
     } 

     static mapping = { 
       className formula: 'CLASS' 
     } 
} 

Ora cosa posso utilizzare questo campo className nei miei cercatori dinamici e criteri di query pure.Così posso fare qualcosa come

List<AdvertisingMaterial>adMaterials=AdvertisingMaterial.findAllByClassName("com.project.FlashAd") 

static mapping = { 
       fullName formula: "CONCAT(FIRST_NAME,' ',LAST_NAME)" 
       totalAmount formula: "SUM(AMOUNT)" 
} 
1

Ho usato un hack. Ho aggiunto un campo Long updateTrigger alla mia genitore classe dominio e un metodo touch:

class Parent { 
    Long updateTrigger 

    static mapping = { 
     autoTimestamp true 
    } 

    static constraints = { 
     updateTrigger(nullable:true) 
    } 

    public touch() { 
     if (updateTrigger == null) updateTrigger = 0 
     updateTrigger++ 
     this 
    } 

Nella aggiornamento/salvare le azioni del bambino regolatore , mi basta chiamare:

child_instance.save() // save the child 
child_instance.parent.touch().save() // updates parent's time stamp 

Questo incrementerà il valore updateTrigger e lo save() aggiornerà automaticamente il campo lastUpdated grazie allo autoTimestamp impostato su true nel ma pping. updatedTrigger è impostato per essere annullabile in modo che non invalidi alcuna tabella di database esistente e, pertanto, possa essere aggiunto in qualsiasi momento a qualsiasi classe di dominio.

Problemi correlati