6
votes

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?

3

3 Answers

2
votes

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()
}
2
votes

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')"

1
votes

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>