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?
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()
}
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')"
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>
Related
I have a plain Grails 3.3.2 app. I can run tests just fine with gradle test integrationTest. But when I try to right click and run a test class or a single tests or the entire test suite in IntelliJ, I get:
No GORM implementations configured. Ensure GORM has been initialized correctly
This happens when I run them as jUnit tests.
If i try to run as Grails tests, I get:
No tests found for given includes
I have tried to clean the build and reset caches in IntelliJ, but nothing seems to help. Unfortunately I don't know what I've done to put Grails + IntelliJ in this state either. It used to work, but now it doesn't, and I'm not sure what has changed.
I found a "fix", sort of.
I edited the #IntegrationTest annotation on my test class from:
#Integration
to
#Integration(applicationClass = Application.class)
And now it works again.
Interestingly, if I change it back to just #Integration, it still works. But if I run a clean, and rerun, it stops working. So something is definitely wonky here.
EDIT: I wrote the following test case:
CompilerConfiguration configuration = new CompilerConfiguration()
configuration.setTolerance(1)
println new File("src/integration-test/groovy/my/package/Mytest.groovy").isFile()
// true
def source = new SourceUnit(
new File("src/integration-test/groovy/my/package/MyTest.groovy"),
configuration,
null,
new ErrorCollector(configuration))
println source
// org.codehaus.groovy.control.SourceUnit#19bbb216
println source.source
// org.codehaus.groovy.control.io.FileReaderSource#6cfac0bd
println source.source.URI
// file:/path/to/my/app/src/integration-test/groovy/my/package/MyTest.groovy
println MainClassFinder.searchMainClass(source.source.URI)
// null
The AST transformation #Integration runs MainClassFinder.searchMainClass when the applicationClass property is not set. So this seems to indicate that it for some reason isn't able to automatically find the application class for my app based on the integration test. Then again, I'm not really sure which source unit it actually gets when it runs, so my test case might not be realistic.
I'm trying to use the run-script command with one of my services in Grails 3.
I have all my services marked with the #Transactional tag. I made a "standalone" groovy file in the folder src/main/groovy that declares one of the services and wants to call a method on it.
My stand-alone groovy file declares a dataSource and sets it like this:
def dataSource = new OracleDataSource(URL: 'jdbc:oracle:thin:#localhost:1521:local', user: 'test', password: '');
I can verify it works within the stand-alone groovy file by doing this:
sql = new Sql(dataSource);
sql.eachRow("SELECT COUNT(*) AS MYCOUNT FROM MYTABLE") {
myCount = it."MYCOUNT";
}
and it works fine.
I then pass the dataSource to my service class as a param. Note that when I run my Grails app as a "normal" Grails app, I don't need to do this, as the service "already knows" how to initialize the dataSource property that it has. But when running my stand-alone groovy file with "grails run-script" and wanting to use the service, I do this:
applicationFunctionService.setSession(dataSource);
But then afterwards when I call a method on my service that involves doing an SQL/database-interaction, it throws this error (when using grails run-script)
Script execution error: No transactionManager was specified. Using #Transactional or #Rollback requires a valid configured transaction manager. If you are running in a unit test ensure the test has been properly configured and that you run the test suite not an individual test method.
:runScript FAILED
Note that my intention is not to do a test per say... I actually want to have a "stand-alone" groovy file that invokes my Grails service within the Grails-context. I'd also like to leave the service as-is with the #Transactional tag. Though I wouldn't mind "turning #Transaction off" within the context of my stand-alone groovy class, if that's possible.
Is there a way to deal with this error?
I have a groovy script, created with grails create-script.
How can I import domain class from my grails app, like
dep p = new User(name: 'Karl')
p.save()
If I try this I get unable to resolve class User.
Thanks for help.
I'm using Grails 3.1.4, I've created some domain object and written unit test.
Tests are executed fine on my computer.
Tests on my computer
But on the other developpers computers and on the continous integration platform, tests fail with exception :
java.lang.IllegalStateException: Either class [ ] is not a domain class or GORM has not been initialized correctly or has already been shutdown. If you are unit testing your entities using the mocking APIs
at org.grails.datastore.gorm.GormEnhancer.stateException(GormEnhancer.groovy:159)
at org.grails.datastore.gorm.GormEnhancer.findValidationApi(GormEnhancer.groovy:173)
at org.grails.datastore.gorm.GormValidateable$Trait$Helper.currentGormValidationApi(GormValidateable.groovy:120)
at org.grails.datastore.gorm.GormValidateable$Trait$Helper.validate(GormValidateable.groovy:87)
at com.cscinfo.platform.constraint.CascadeValidationConstraint.validateValue(CascadeValidationConstraint.groovy:43)
at com.cscinfo.platform.constraint.CascadeValidationConstraint.processValidateWithVetoing_closure1(CascadeValidationConstraint.groovy:29)
at groovy.lang.Closure.call(Closure.java:426)
at com.cscinfo.platform.constraint.CascadeValidationConstraint.processValidateWithVetoing(CascadeValidationConstraint.groovy:28)
at grails.validation.AbstractVetoingConstraint.validateWithVetoing(AbstractVetoingConstraint.java:33)
at grails.validation.ConstrainedProperty.validate(ConstrainedProperty.java:967)
at org.grails.validation.GrailsDomainClassValidator.validatePropertyWithConstraint(GrailsDomainClassValidator.java:211)
at org.grails.validation.GrailsDomainClassValidator.validate(GrailsDomainClassValidator.java:81)
at org.grails.datastore.gorm.GormValidationApi.doValidate(GormValidationApi.groovy:89)
at org.grails.datastore.gorm.GormValidationApi.validate(GormValidationApi.groovy:161)
at org.grails.datastore.gorm.GormValidateable$Trait$Helper.validate(GormValidateable.groovy:87)
at api.mails.MailSpec.Test la validation d'un mail incorrect 2(MailSpec.groovy:66)
It seems that GORM can't get my domain object.
I can't reproduce the bug on my computer.
Any help or documentation will be appreciated.
Thanks !
The problem was some oject in my Unit test were not mocked.
I put an array of object in my #Mock annotation and now, it works on my continuous integration platform.
#TestFor(SMTPMailerService)
#Mock([Mail, DestinataireMail, PieceJointeMail])
class SMTPMailerServiceSpec extends Specification {
Hope it will help someone !
The following artical code works in 'grails console'. But when I try to run it in STS its giving compile error for the domain class.
http://timsporcic.github.io/GORM-Recipes/
Is it possible to run in STS, I want to test to GORM methods before using it in contolers. even console command from STS is not working.
trying to run like this:
class Test {
static main(args) {
new BootStrap().init()
println Person.get(1)
}
}
thanks
Run as > Groovy Script will not work. grails console works different, because you have you application fully initialized (same for run-app and test-app).
If you want to test your BootStrap class I suggest you to create one integration test. This will also ensure that, if you change your class, the logic still works.