2010-02-09 7 views
21

J'ai une table qui a des enregistrements qui doivent être périodiquement effacés selon un ensemble de critères.Comment supprimer en bloc des enregistrements dans Grails/GORM?

Je me attendais à ce que je pouvais utiliser le générateur de critères pour supprimer uniquement les enregistrements, mais qui ne parvient parce qu'il n'y a pas de méthode delete sur des critères ...

def c = Agency.createCriteria() 
c.delete 
{ 
    eq("agency", "XXX") 
} 

Je pensais que je première requête pour la définir et puis supprimer que ...

def c = Agency.createCriteria() 
def deletions = c 
{ 
    eq("agency", "XXX") 
} 
deletions.delete 

Cela échoue également pour la même raison, objet différent.

Alors, quelle est la bonne façon de faire cela? Il semble excessif (pervers) que je devrais itérer à travers l'ensemble des résultats appelant delete() sur chaque élément.

Je sais que je peux former une requête à exécuter directement en HQL ou en SQL mais cela ne va pas non plus. Le constructeur de critères est-il uniquement destiné à la récupération?

Merci

Répondre

19

De l'User Guide about deleting objects:

Notez que Grails ne fournit pas une méthode de deleteAll comme la suppression des données est découragé et peut souvent être évité par drapeaux booléen/logique.

Si vous avez vraiment besoin de données batch supprimer vous pouvez utiliser la méthode executeUpdate pour faire lots DML:

Customer.executeUpdate("delete Customer c where c.name = :oldName", [oldName:"Fred"]) 
+22

oui, c'est comme ça que je le fais, mais c'est un peu fou que je ne puisse pas utiliser de critères. DELETE est une partie valide de la sémantique des requêtes et supportée par tous les SGBDR et une chose parfaitement valide, malgré ce que les auteurs d'Hibernate/GORM peuvent penser. Dans mon cas, il serait très mauvais de laisser les enregistrements périmés dans le tableau. – Simon

+1

comme références JesperSM: Maintenant Grails 2+ a un deleteAll() sur DetachedCriteria. –

+3

Cela fonctionne. Dommage cependant qu'il ne cascade pas la suppression des lignes dans les tables enfant. Il donne ensuite une 'violation de la contrainte d'intégrité '. Testé dans '2.3.7'. – Guus

12

Si vous voulez éviter HQL Je suggère d'utiliser la liste de Gorm() , supprimer() et l'opérateur de diffusion de Groovy:

 
def agencyList = Agency.createCriteria().list { 
    eq("agency", "XXX") 
} 
agencyList*.delete() 
+1

ouah!qu'est-ce que ça fait? J'ai essayé exactement ceci mais sans le * et ai obtenu une erreur de compilateur ... – Simon

+1

Le *. est l'opérateur de propagation Groovy http://groovy.codehaus.org/Operators#Operators-SpreadOperator (.) Dans l'exemple de Sbglasius, il appelle la méthode delete() sur un élément de la collection qui a été retourné. –

+0

Je suis tombé sur une exception java.util.ConcurrentModificationException lorsque j'utilisais cette méthode ... J'ai donc arrêté d'utiliser l'opérateur spread et créé une boucle while en utilisant l'itérateur selon les solutions sur http://stackoverflow.com/questions/1816196/java- util-concurrmodificationexception-in-non-multithreaded-program – khylo

48

Avec Grails 2.0, vous pouvez utiliser une requête individuelle comme ceci:

Agency.where { }.deleteAll() 

Notez que vous ne recevez pas les auditeurs et ainsi de suite exécutés, mais il ne s'exécute à travers la base de données, et il est compatible avec les choses de domaine moqué, comme dans:

void testWhatever() { 
    mockDomain(Agency, []) 
    saveABunchOfAgencies() // saves 10 of 'em 
    assert Agency.count() == 10 

    Agency.where { }.deleteAll() 

    assert Agency.count() == 0 // Joy! 
} 

Cela dit les mocks d'essai de l'unité GORM ont un tas de getchas mais sont en général assez soignés.

+0

Cela ressemble à la le meilleur à coup sûr. Je l'utilise. – Peter

+1

Documentation sur les grils pour cela: http://grails.org/doc/latest/guide/single.html#whereQueries – GreenGiant

+0

Jesper, je suis totalement d'accord avec "les simulations de tests unitaires GORM ont un tas de pièges". Tout endroit où ils sont documentés? –

Questions connexes