Grails 2.5,beforeDelete 无法访问一对多关系
Grails 2.5, beforeDelete cannot access one-to-many relationship
这里使用 Grails 2.5.6。我正在尝试在 beforeDelete GORM 事件中从我的域 class 访问一组字符串。在到达我在 beforeDelete 中的断点之前,我在数据库日志中看到了这个集合的删除。
我在我的域 class.
下面的 println(strings) 上收到 NullPointerException
我的测试域 class 看起来像
class DeleteTest {
Integer id
Set<String> stringSet
String prop1
String prop2
static hasMany = [stringSet: String]
static constraints = {
prop1(maxSize: 20)
prop2(maxSize: 20)
}
static mapping = {
stringSet(joinTable: [column: 'delete_test_string_set', length: 15])
}
def beforeDelete() {
withNewSession {
Set<String> strings = this."stringSet"
println(strings)
}
}
}
我做了一个这样的测试控制器。
class DeleteTestController {
def create() {
DeleteTest test = null
DeleteTest.withTransaction {
test = new DeleteTest(
prop1: 'Test',
prop2: 'another test',
stringSet: ['str1', 'str2', 'str3']
).save()
}
render (test as JSON)
}
def delete() {
DeleteTest test = DeleteTest.findByProp1('Test')
DeleteTest.withTransaction {
test.delete()
}
render(test as JSON)
}
}
如何在 beforeDelete 事件中获取我的 stringSet?
一个简单的方法是确保在调用删除之前加载 stringSet
。但是,这里显然发生了一些奇怪的行为,我将描述到目前为止我发现的内容。
简单回答
def delete() {
DeleteTest test = DeleteTest.findByProp1('Test')
test.stringSet?.size() // <-- force load here
DeleteTest.withTransaction {
test.delete()
}
render(test as JSON)
}
其他注意事项
我尝试让 stringSet
预先加载。这没有按预期工作,在 beforeDelete
代码中它通常是单个值或空白。
我还尝试将 StringSet 设为一个 Set,我在其中定义了一个包含该值的 GORM 对象 MyString。这确实有效(尽管我不得不急切地获取它),但我认为这不是您案例的有效解决方案,因为我假设您已经有数据并且不能只是替换它。
基于一些调试挖掘,我猜测(但它确实只是一个猜测)集合在 beforeDelete
事件触发之前被删除,所以它不能延迟加载点即使在一个新的交易。我希望其他人可以权衡一下这是否正确,但是现在越来越难找到 grails 2 专业知识。
这里使用 Grails 2.5.6。我正在尝试在 beforeDelete GORM 事件中从我的域 class 访问一组字符串。在到达我在 beforeDelete 中的断点之前,我在数据库日志中看到了这个集合的删除。
我在我的域 class.
下面的 println(strings) 上收到 NullPointerException我的测试域 class 看起来像
class DeleteTest {
Integer id
Set<String> stringSet
String prop1
String prop2
static hasMany = [stringSet: String]
static constraints = {
prop1(maxSize: 20)
prop2(maxSize: 20)
}
static mapping = {
stringSet(joinTable: [column: 'delete_test_string_set', length: 15])
}
def beforeDelete() {
withNewSession {
Set<String> strings = this."stringSet"
println(strings)
}
}
}
我做了一个这样的测试控制器。
class DeleteTestController {
def create() {
DeleteTest test = null
DeleteTest.withTransaction {
test = new DeleteTest(
prop1: 'Test',
prop2: 'another test',
stringSet: ['str1', 'str2', 'str3']
).save()
}
render (test as JSON)
}
def delete() {
DeleteTest test = DeleteTest.findByProp1('Test')
DeleteTest.withTransaction {
test.delete()
}
render(test as JSON)
}
}
如何在 beforeDelete 事件中获取我的 stringSet?
一个简单的方法是确保在调用删除之前加载 stringSet
。但是,这里显然发生了一些奇怪的行为,我将描述到目前为止我发现的内容。
简单回答
def delete() {
DeleteTest test = DeleteTest.findByProp1('Test')
test.stringSet?.size() // <-- force load here
DeleteTest.withTransaction {
test.delete()
}
render(test as JSON)
}
其他注意事项
我尝试让 stringSet
预先加载。这没有按预期工作,在 beforeDelete
代码中它通常是单个值或空白。
我还尝试将 StringSet 设为一个 Set,我在其中定义了一个包含该值的 GORM 对象 MyString。这确实有效(尽管我不得不急切地获取它),但我认为这不是您案例的有效解决方案,因为我假设您已经有数据并且不能只是替换它。
基于一些调试挖掘,我猜测(但它确实只是一个猜测)集合在 beforeDelete
事件触发之前被删除,所以它不能延迟加载点即使在一个新的交易。我希望其他人可以权衡一下这是否正确,但是现在越来越难找到 grails 2 专业知识。