带有@GrailsCompileStatic 注释的Grails GORM class 在静态映射闭包table、版本、autoTimestamp 中显示为未解析的符号

Grails GORM class with @GrailsCompileStatic annotation shows in the static mapping closure table, version, autoTimestamp as unresolved symbol

参考文献:

  1. https://youtrack.jetbrains.com/issue/IDEA-206196
  2. https://youtrack.jetbrains.com/issue/IDEA-207415?_ga=2.103698112.1724644326.1581075934-247190714.1566820331
package de.equeo.requestcode

import grails.compiler.GrailsCompileStatic

@GrailsCompileStatic
class Feature {

    String name

    static mapping = {
        table 'rq_feature'
        version false
        autoTimestamp false
    }

}

这仅在 IDE 中导致错误(在 grails run-app 或编译时工作正常):

我以前从来没有花太多时间来找出解决方法,但现在我有了解决方法。

第一个解决方法(推荐)

正如 @JamesKleeh 回答的那样,您甚至不需要为类型安全的 DSL 定义上述方法:

package com.wizpanda.hooman

import grails.compiler.GrailsCompileStatic

import static grails.gorm.hibernate.mapping.MappingBuilder.orm

@GrailsCompileStatic
class User {

    String firstName
    String lastName
    String bio
    String email

    static final mapping = orm {
        table "rq_feature"
        version false
        autoTimestamp false
        property("bio", [type: "text"])
        property("firstName", {
            column([name: "fn"])
        })
    }

}

第二种解决方法

我从 https://github.com/wizpanda/kernel/blob/v2.1.6/src/main/groovy/com/wizpanda/logging/KernelLogging.groovy#L63 中使用了我自己的逻辑,并创建了一个静态方法 applyFooMapping,它使用 @DelegatesTo 注释来欺骗 IDE

import grails.compiler.GrailsCompileStatic
import org.grails.orm.hibernate.cfg.HibernateMappingBuilder

@GrailsCompileStatic
class Feature {

    String name

    /**
     * This is to solve the IntelliJ Idea problem as defined
     * @param delegate
     * @param closure
     * @return
     */
    static applyFooMapping(Object delegate, @DelegatesTo(HibernateMappingBuilder) Closure closure) {
        closure.delegate = delegate
        closure.resolveStrategy = Closure.DELEGATE_ONLY
        closure.call()
    }
    
    static mapping = {
        applyFooMapping(delegate) {
            table 'rq_feature'
            version false
            autoTimestamp false
        }
    }

}

干杯!

第三个解决方法(改进为第二个)

要为多个域解决此问题,请在 src/main/groovy/some/package/AbstractFooDomain 中创建 groovy class:

@GrailsCompileStatic
abstract class AbstractFooDomain {

    /**
     * This is to solve the IntelliJ Idea problem as defined
     * @param delegate
     * @param closure
     * @return
     */
    static applyFooMapping(Object delegate, @DelegatesTo(HibernateMappingBuilder) Closure closure) {
        closure.delegate = delegate
        closure.resolveStrategy = Closure.DELEGATE_ONLY
        closure.call()
    }
}

现在,在您的域中使用它 classes:


@GrailsCompileStatic
class Feature extends AbstractFooDomain {

    String name

    static mapping = {
        applyFooMapping(delegate) {
            table 'rq_feature'
            version false
            autoTimestamp false
        }
    }

}

再次欢呼!

您可以使用 GORM 6.1 中添加的内置类型安全 dsl 来代替这样做

import static grails.gorm.hibernate.mapping.MappingBuilder.*

class Book {
    String title

    static final mapping = orm {