You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Grails 4.x下DomainClassMarshaller无法获取PersistentEntity问题求助

问题核心原因
  • 你声明的 grailsDomainClassMappingContext 是实例属性,仅能被类的实例方法访问;而 appendMarshaller 是静态方法,静态方法及其内部的闭包无法直接引用实例属性,这就是 MissingPropertyException 的触发根源。
  • Grails 的依赖注入仅对 Spring 管理的 Bean 的实例属性生效,无法注入到静态作用域中,这也是你后续尝试用 grailsApplication.mappingContext 实现时仍报错的原因。
标准修复方案

按以下步骤修改即可解决问题:

  • 第一步:将 DomainClassMarshaller 注册为 Spring 管理的 Bean
    给类添加 @Singleton 注解(放在类定义上方),确保 Grails 会对该类执行依赖注入逻辑。
  • 第二步:移除 appendMarshaller 方法的 static 修饰符
    让该方法成为实例方法,其内部的闭包就能正常访问类实例注入的 grailsDomainClassMappingContext。
  • 第三步:如需在其他类调用该方法,不要用静态调用方式,改为先注入 DomainClassMarshaller 实例,再调用实例方法。

修正后的完整代码示例:

import groovy.util.Singleton

// 注册为 Spring 管理的 Bean,支持依赖注入
@Singleton
class DomainClassMarshaller {
    def grailsDomainClassMappingContext
    public static final List<String> appendFields = ['id']

    // 移除 static 修饰符,改为实例方法
    Closure appendMarshaller(String clazz, List<String> fieldsToInclude) {
        return { domainItem ->
            def domain = grailsDomainClassMappingContext.getPersistentEntity(clazz)
            def results = [:]
            domain.persistentProperties.each { field ->
                results[field.name] = domainItem[field.name]
            }
            def fields = []
            fields.addAll(appendFields)
            fields.addAll(fieldsToInclude)
            fields.each { name ->
                results[name] = domainItem[name]
            }
            return results
        }
    }
}
兼容旧代码的临时静态方案

如果原业务逻辑必须保留静态方法的调用方式,可采用以下临时方案(不推荐长期使用):

  • 手动将注入的实例 Bean 赋值给静态属性,让静态作用域能访问到依赖:
class DomainClassMarshaller {
    // 改为静态属性
    static grailsDomainClassMappingContext
    public static final List<String> appendFields = ['id']

    // 实例注入方法,赋值给静态属性
    @Autowired
    void injectMappingContext(def grailsDomainClassMappingContext) {
        this.grailsDomainClassMappingContext = grailsDomainClassMappingContext
    }

    static Closure appendMarshaller(String clazz, List<String> fieldsToInclude) {
        return { domainItem ->
            def domain = grailsDomainClassMappingContext.getPersistentEntity(clazz)
            def results = [:]
            domain.persistentProperties.each { field ->
                results[field.name] = domainItem[field.name]
            }
            def fields = []
            fields.addAll(appendFields)
            fields.addAll(fieldsToInclude)
            fields.each { name ->
                results[name] = domainItem[name]
            }
            return results
        }
    }
}

内容的提问来源于stack exchange,提问作者wonder.glen

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.27 08:36:03