rest - 资源注释域上集合属性的 Grails REST 更新不起作用
问题描述
我在带@Resource
注释的域类和RestfulController
为所述类自动生成的问题上遇到了一个非常奇怪的问题。具体来说,我的 Domain 实体在 type中Product
有一个 CollectionhasMany
属性,我正在尝试使用 PUT在实例中进行更新,但更新不起作用。parts
Part
parts
Product
我的包含域实体Product
定义如下:
package com.test
import grails.rest.Resource
@Resource(uri='/rest/product', formats=['json', 'xml'])
class Product
{
Integer completed // Completed quantity
Set<Part> parts // Each requested product has a list of requested parts
static hasMany = [parts: Part]
static constraints = {
parts minSize: 1
}
}
我的部分定义如下:
package com.test
import grails.rest.Resource
@Resource(uri='/rest/part', formats=['json', 'xml'])
class Part
{
String identifier // Each part must have an identifier
Double weight // How much does each unit of this product part weigh
Product product // The product request that this part request belongs to
static belongsTo = [product: Product]
static constraints = {
}
}
在我的 BootStrap.groovy 中,我已经为两个产品创建了两个部分(总共 4 个部分)。
package broken.put.array.property
import com.test.Product
import com.test.Part
class BootStrap {
def init = { servletContext ->
Product product = Product.findOrSaveWhere(completed: 4)
product.addToParts(new Part(product: product, weight: 1237, identifier: "part1").save(failOnError: true, flush: true))
product.addToParts(new Part(product: product, weight: 1236, identifier: "part2").save(failOnError: true, flush: true))
product.save(failOnError: true, flush: true)
Product product2 = Product.findOrSaveWhere(completed: 3)
product2.addToParts(new Part(product: product2, weight: 1235, identifier: "part3").save(failOnError: true, flush: true))
product2.addToParts(new Part(product: product2, weight: 1234, identifier: "part4").save(failOnError: true, flush: true))
product2.save(failOnError: true, flush: true)
}
def destroy = {
}
}
因此,在运行应用程序后,我执行以下操作:
$ curl -X PUT "http://localhost:8080/product/1" -H "Content-Type:application/json" -d '{"parts" : [{ "id": 1 }], "completed": 3}'
将 ID 为 1 的parts
Collection 属性Product
从具有 2 个部分更新为具有 1 个部分。出于某种原因,更新总是最终根本没有真正修改 parts 属性,如响应 JSON 中所示:
{"id":1,"parts":[{"id":2},{"id":1}],"completed":3}
所以我决定通过让我的@Resource
注释包含一个superClass
指向我自己的控制器的属性来调试它,我可以在其中做一些println
. 我从默认的 RestfulController 中复制了update()
方法的主体,并在其中添加了 println 语句以找出问题所在。经过一些实验,我了解到在设置instance.properties
为之后getObjectToBind()
,其中的parts
Collection 仍然具有旧值(ID 为 1 和 2 的 Part 对象),而不是我在 PUT 的 JSON 正文中发送的值(具有 ID 的单个 Part 对象1)。
但是我发现还有一些非常令人惊讶的事情,如果我在设置为 的行之前放置了一个println
打印输出的语句,那么更新会突然与我的预期行为一起工作。除了那个位置之外的任何东西都不会做。它必须打印.instance.properties
getObjectToBind()
PUT
instance.properties
当我意识到这与巫毒教接壤时,我以已上传到TinyUpload的 zip 文件的形式创建了一个独立的测试用例项目。我的 grails 版本是 3.3.6。很想听听任何见过这种情况的人,或者谁能帮助我理解为什么会发生这种情况。您需要做的就是将 zip 文件解压缩到一个文件夹中,然后使用 grails dev run-app 运行它。代码的当前状态将该println
行(第 42 行)注释掉了,src/main/groovy/com/test/ReactAdminRestfulController.groovy
因此您可以看到我上面描述的内容。但是取消注释该行并重新运行应用程序将给出正确的行为。
解决方案
推荐阅读
- websphere - 403 Forbidden (RP) 在使用 tWAS 配置 App ID 时遇到登录失败
- collections - 无锁非分配集合
- java - 如何杀死从我的 java 应用程序启动的 cmd 进程?
- jboss - JBoss 7.1 在查找中加载 DefaultManagedExecutorService 失败(“java:comp/DefaultManagedExecutorService”);
- python - 在“g”上运行“min”方法时,如何通过一组“x”计算“g(x)”?
- sql-server - 如何在不同数据库、同一服务器中对表进行 FULLTEXT 索引
- xero-api - 识别公司 - API
- java - 字符串列表始终为空
- azure - 如何删除 Azure Application Insights 故障排除指南
- php - 如何覆盖 PHPMAILER 异常?