0

Adding the @GrailsCompileStatic annotation to a method or class allows the usage of dynamic GORM finders, e.g. findAllByIdAndProperty(). However, adding the annotation does not allow for domainClass.withTransaction(), which is also a GORM AST addition. Why?

(Using grails-2.5.3)

UPDATE (05/10/16 - 10:25AM) @jeff-scott-brown is right, it does work in general, so here is the code that fails with @GrailsCompileStatic:

...
RestfulApiService service = ServiceUtils.getService(resourceName)
service.resourceClass.withTransaction { /* do something */ }

(resourceClass is of type Class)

The error:

Compilation error: startup failed:
C:\...\myfile.groovy: 100: [Static type checking] - Cannot find matching method java.lang.Class#withTransaction(groovy.lang.Closure). Please check if the declared type is right and if the method exists.
@ line 100, column 13.
           service.resourceClass.withTransaction {
           ^

Why does withTransaction() fail in this case once the annotation is added?

Daniel Salvadori
  • 427
  • 6
  • 15

1 Answers1

0

Why does @GrailsCompileStatic allow calling dynamic GORM finders but not domainClass.withTransaction()?

It does. The code at https://github.com/jeffbrown/withtx/blob/master/grails-app/controllers/demo/DemoController.groovy compiles.

import grails.compiler.GrailsCompileStatic

@GrailsCompileStatic
class DemoController {

    def index() {
        Person.withTransaction {
            // ...
        }
        render 'Success!'
    }
}
Jeff Scott Brown
  • 26,804
  • 2
  • 30
  • 47
  • The reasons that dynamic finders are allowed are not the same reasons that `withTransaction` is allowed. `withTransaction` is allowed because it can be statically verified. The reason dynamic finders are allowed is that we have a type checking extension that knows about dynamic finder calls and will turn those into dynamically dispatched in a class where everything else is being statically dispatched. – Jeff Scott Brown May 09 '16 at 23:11
  • Ok I see - but why does `withTransaction()` fail in my case? I've added the failing code to the original post. – Daniel Salvadori May 10 '16 at 18:12
  • Because the compiler can't verify that `service.resourceClass` is a domain class. – Jeff Scott Brown May 10 '16 at 21:45
  • You can't invoke `withTransaction` on any `Class`. The reference has to point to a domain class in particular and the compile has to be able to guarantee that. That is the point of static type checking. If the return type of your `getResourceClass` method is `java.lang.Class`, then that would be problematic for the static type checker. – Jeff Scott Brown May 10 '16 at 21:47
  • had this issue after upgrading my java from java 1.8 to java 1.11. it's really frustrating because I had to remove the @GrailsCompileStatic from some sensitive classes to prevent the error – daptordarattler Aug 14 '20 at 12:57