Grails:在地图构造函数中设置瞬态字段
Posted
技术标签:
【中文标题】Grails:在地图构造函数中设置瞬态字段【英文标题】:Grails: setting transient fields in the map constructor 【发布时间】:2014-11-03 03:20:23 【问题描述】:我正在尝试将属性映射保留为单个 JSON 编码列,如 this question 所示。
我遇到的问题是显然无法在默认地图构造函数中设置瞬态属性。给定任何瞬态字段:
class Test
//...
String foo
static transients = ['foo']
似乎 map 构造函数(Grails 以各种方式覆盖)只是丢弃了瞬态字段:
groovy:000> t = new Test(foo:'bar')
===> Test : (unsaved)
groovy:000> t.foo
===> null
虽然直接赋值(通过 setter 方法)按预期工作:
groovy:000> c.foo = 'bar'
===> bar
groovy:000> c.foo
===> bar
有没有办法让地图构造函数接受瞬态字段?
或者更确切地说:有没有更好的方法将Map
持久化为单个 JSON 编码的 DB 字段,而不是 linked question 中显示的方法?
这是完整的例子:
import grails.converters.JSON
class JsonMap
Map data
String dataAsJSON
static transients = ['data']
def afterLoad() data = JSON.parse(dataAsJSON)
def beforeValidate() dataAsJSON = data as JSON
我可以使用设置器设置data
(然后将其转换为dataAsJSON
),但不能使用地图构造函数。
【问题讨论】:
暂态属性不会被持久化。我认为这是不可能的。 我知道他们没有持久化。如果您阅读链接的问题,则 Map 属性是故意声明为瞬态的。 【参考方案1】:GORM 中的 map 构造函数使用数据绑定机制,transient 属性默认是不可绑定的。但是您可以使用 bindable constraint
覆盖它class Test
//...
String foo
static transients = ['foo']
static constraints =
foo bindable:true
【讨论】:
这正是我想要的!谢谢【参考方案2】:我也回复了你的original question,说你不需要json转换就可以实现你需要的。但是,如果你非常需要 json 转换,为什么不在你的 getter/setter 中实现呢?
class Test
String propsAsJson
static transients = ['props']
public Map getProps()
return JSON.parse(propsAsJson)
public void setProps(Map props)
propsAsJson = props as JSON
//So you can do
Test t = new Test(props : ["foo" : "bar"])
t.save()
通过这种方式,您封装了转换的东西,并且在 DB 中您的属性为 Json。
【讨论】:
这不是每次修改属性时都会将数据转换为 Json 还是只在保存时转换?【参考方案3】:您可以通过将 JSON 转换方法添加到您的域类来简化您的案例,它们应该与 GORMing 无关:
class Test
String title
void titleFromJSON( json )
title = json.toStringOfSomeKind()
def titleAsJSON()
new JSON( title )
【讨论】:
这提供的功能比现有的 afterLoad / beforeValidate 方法少,并且没有解决使用 map 构造函数设置瞬态值的问题。以上是关于Grails:在地图构造函数中设置瞬态字段的主要内容,如果未能解决你的问题,请参考以下文章