views:

465

answers:

3

Hi, I'm a grails newbie (and a groovy newbie), and I'm working through some grails tutorials. As a new user, the grails shell is a really useful little tool for me, but I can't figure out how to make it see my classes and objects. Here's what I'm trying:

% grails create-app test
% cd test
% grails create-domain-class com.test.TestObj
% grails shell
groovy:000> new TestObj()
ERROR org.codehaus.groovy.control.MultipleCompilationErrorsException: startup failed, groovysh_evaluate: 2: unable to resolve class TestObj

I was under the impression that the grails shell could see all of the controllers, services, and domain objects. What's up with this? Do I need to do something else here?

I tried one other thing:

groovy:000> foo = new com.test.TestObj();
===> com.test.TestObj : null
groovy:000> foo.save 
ERROR groovy.lang.MissingPropertyException: No such property: save for class: com.test.TestObj

What am I doing wrong?

EDIT: Okay, I saw the answers about using the full name and also using .save() instead of .save. But what about this one?

groovy:000> new com.test.TestObj().save()
ERROR org.hibernate.HibernateException: No Hibernate Session bound to thread, and configuration does not allow creation of non-transactional one here

What'd I do wrong this time?

+2  A: 

You need the package since it's possible (but not a good idea) to have two domain classes with the same name in different packages.

For the 2nd session it should be foo.save(), not foo.save.

I prefer the console, it's a lot easier to work with. Run 'grails console' and the Swing app will start. It's a little different from the regular Groovy console in that it's got an implicit 'ctx' variable available which is the Spring application context. You can use that to access services and other Spring beans via "ctx.getBean('fooService')"

Burt Beckwith
Thanks, good advice! P.S. I have one more question, save() produces a Hibernate exception. Suggestions?
CaptainAwesomePants
Also, "ctx" seems to also be available in my shell. Maybe they added it in 1.2?
CaptainAwesomePants
+1  A: 

you will have to import com.test.TestObj or reference it by new com.test.TestObj() as you have shown.

Note that 'save' is not a propery but a dynamic method that Grails decorates the domain class with at runtime.

groovy:000> foo = new com.test.TestObj();
===> com.test.TestObj : null
groovy:000> foo.save()
===> com.test.TestObj : 2
groovy:000> 
Colin Harrington
Ahhh, I knew that save was a method, but I'm new enough to groovy not to know that I can't call a method without parentheses :)Do you know what's up with the Hibernate session exception I'm seeing now?
CaptainAwesomePants
+1  A: 

I second Burt's advice to use the console instead of the shell. Regarding the exception:

groovy:000> new com.test.TestObj().save()
ERROR org.hibernate.HibernateException: No Hibernate Session bound to thread, and configuration does not allow creation of non-transactional one here

Can you try explicitly running this code with a transaction:

import com.test.TestObj

TestObj.withTransaction{ status ->
    TestObj().save()
}
Don
Yes, withTransaction works perfectly. I wonder why I need to add that. Examples online don't seem to mention it.
CaptainAwesomePants
You shouldn't need to add that, but I figured it might solve your problem. BY running your code within a transaction, your forcing the creation of a hibernate session (which is otherwise missing).
Don