2009-08-04 8 views
2

La documentation Grails définit une méthode statique « count », défini dans la documentation comme ceci:Je ne peux pas obtenir Domain.count() méthode statique pour travailler

 
Description 

    Counts the number of instances in the database and returns the result 

Parameters 

    None 

Example 

    def noOfBooks = Book.count() 

Cependant, chaque fois que je l'appelle, je reçois ce Erreur! Je simplement ajouté un appel au nom de ma classe (Domain Company) comme celui-ci à un contrôleur de travail

def companies = Company.count() 

et quand il exectutes cette ligne, il explose avec l'erreur suivante

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'pluginManager' defined in ServletContext resource [/WEB-INF/applicationContext.xml]: Invocation of init method failed; nested exception is java.lang.RuntimeException: Unable to locate constructor with Class parameter for class org.codehaus.groovy.grails.commons.DefaultGrailsControllerClass 

Autre , travail, code dans le contrôleur (pré-généré avec les commandes d'échafaudage statique) accès Company.get (...) etc, sans erreur

Qu'est-ce que je fais mal?

Répondre

1

La réponse courte est que la méthode count() et beaucoup d'autres sont ajoutées à la métaClass à l'exécution après le chargement du plugin Hibernate. count() n'est pas une méthode statique disponible au moment de la compilation comme le fait Java, mais plutôt une méthode statique qui est ajoutée à la métaClasse du domaine lors de l'exécution (apparemment après l'analyse des contrôleurs).

Pourquoi? Parce que cela n'a pas de sens d'avoir count(), get() ou read(), etc. méthodes qu'après Hibernate/GORM est initialisé. Il ne serait pas connecté à la source de données et les méthodes seraient invalides.

Je ne peux pas m'empêcher de me demander pourquoi vous auriez besoin de mettre une propriété comme ça sur un contrôleur. Dès que vous enregistrez une nouvelle société ou en supprimez une, le compte de votre société est désactivé.

La longue réponse serait plonger dans la source de Grails, De la GORMNamespaceHandler ->GORMSessionFactoryDefinitionParser ->GORMEnhancingBeanPostProcessor ->HibernatePluginSupport ->HibernatePluginSupport.addBasicPersistenceMethods()

+0

Merci pour la réponse! Je commence juste avec Groovy/Grails. Je n'ai aucune expérience antérieure de Java (je l'ai évité pour des raisons philosophiques) mais j'ai écrit de grands systèmes avec tous les autres langages dynamiques de Scheme à Erlang, en plus de beaucoup d'expérience en C/C++ à l'ancienne. Il y a beaucoup de magie dans les coulisses de Groovy/Grails qui rendent les choses très confuses.(Ce serait aussi bien si c'était un vrai langage dynamique et je pourrais ouvrir un shell dans mon environnement, comme Python/Django me le permet, et essayer les choses ...) –

+2

et si vous vouliez ajouter 'Count () 'dans le bootstrap ..? Je suis vraiment fatigué des réponses dans lesquelles les gens ne peuvent pas imaginer où vous auriez besoin d'utiliser un morceau de code - le fait est qu'il y a tellement de situations où vous pourriez avoir besoin d'utiliser un peu de code, et au moment de répondre vous pourriez ne pas comprendre pourquoi cela est nécessaire. Merci de vous en tenir à la question! –

+0

Company.count() fonctionnerait dans la fermeture d'initialisation de BootStrap.groovy. Si l'utilisateur désire un nombre de sociétés au début de l'application, cela doit être fait après l'initialisation de GORM, la connexion à dataSource, etc. Je peux imaginer où vous pourriez vouloir ce comportement - mais l'utilisateur a montré qu'il ne l'avait pas fait t comprendre la différence entre une propriété sur un contrôleur et une action du contrôleur. –

3

Ce

class HomeController { 
    def companies = Company.count() 

    def index = { 
     render(view:"index") 
    } 
} 

ne réussit pas parce que Lael a souligné le nombre La méthode() n'est pas disponible lorsque l'application est démarrée. La méthode count() est une méthode dynamique que GORM a ajoutée aux classes de domaine. Le ressort (le cadre sous-jacent) crée un objet pour chaque artefact (contrôleur/service/classe de domaine, etc.) au démarrage. GORM serait après cela. Spring essaie de créer une classe HomeController, la construction de Home Controller assignera la valeur de company.count aux entreprises au démarrage. Cependant, GORM n'a pas encore démarré, donc les méthodes dynamiques n'ont pas été ajoutées.

Ce code est de toute façon incorrect, s'il fonctionnait, alors la variable d'entreprise n'aurait que la valeur du nombre de sociétés au démarrage de l'application. Une fois que vous serez "habitué" au groovy et aux grails, je pense que vous apprécierez la vitesse de développement.

Espérons que cela aide.

Questions connexes