反映:在 GORM 更新操作的 uint 值上调用 reflect.Value.SetString
reflect: call of reflect.Value.SetString on uint Value on GORM Updates operation
我正在尝试使用 Golang、Gin 和 GORM 构建一个简单的 CRUD 博客。但是,当我想更新博客内容时,触发了以下错误:
reflect: call of reflect.Value.SetString on uint Value
/usr/local/go/src/reflect/value.go:223 (0x10bfb25)
flag.mustBe: panic(&ValueError{methodName(), f.kind()})
/usr/local/go/src/reflect/value.go:2292 (0x10bfaa3)
Value.SetString: v.mustBe(String)
/Users/sam/go/pkg/mod/gorm.io/gorm@v1.23.5/schema/field.go:771 (0x144fcfc)
(*Field).setupValuerAndSetter.func11: field.ReflectValueOf(ctx, value).SetString(data)
/Users/sam/go/pkg/mod/gorm.io/gorm@v1.23.5/callbacks/update.go:144 (0x14b7d9a)
ConvertToAssignments.func2: field.Set(stmt.Context, stmt.ReflectValue, value)
/Users/sam/go/pkg/mod/gorm.io/gorm@v1.23.5/callbacks/update.go:275 (0x14b62fa)
ConvertToAssignments: assignValue(field, value)
/Users/sam/go/pkg/mod/gorm.io/gorm@v1.23.5/callbacks/update.go:73 (0x14b4fe4)
Update.func1: if set := ConvertToAssignments(db.Statement); len(set) != 0 {
/Users/sam/go/pkg/mod/gorm.io/gorm@v1.23.5/callbacks.go:130 (0x146d632)
(*processor).Execute: f(db)
/Users/sam/go/pkg/mod/gorm.io/gorm@v1.23.5/finisher_api.go:372 (0x1476811)
(*DB).Updates: return tx.callbacks.Update().Execute(tx)
/Volumes/Data/Develop/Go/go-blog/controllers/blog.go:65 (0x1693364)
UpdateBlog: models.DB.Model(&blog).Updates(input)
/Users/sam/go/pkg/mod/github.com/gin-gonic/gin@v1.7.7/context.go:168 (0x168a121)
(*Context).Next: c.handlers[c.index](c)
/Users/sam/go/pkg/mod/github.com/gin-gonic/gin@v1.7.7/recovery.go:99 (0x168a10c)
CustomRecoveryWithWriter.func1: c.Next()
/Users/sam/go/pkg/mod/github.com/gin-gonic/gin@v1.7.7/context.go:168 (0x1689246)
(*Context).Next: c.handlers[c.index](c)
/Users/sam/go/pkg/mod/github.com/gin-gonic/gin@v1.7.7/logger.go:241 (0x1689229)
LoggerWithConfig.func1: c.Next()
/Users/sam/go/pkg/mod/github.com/gin-gonic/gin@v1.7.7/context.go:168 (0x1688310)
(*Context).Next: c.handlers[c.index](c)
/Users/sam/go/pkg/mod/github.com/gin-gonic/gin@v1.7.7/gin.go:555 (0x1687f78)
(*Engine).handleHTTPRequest: c.Next()
/Users/sam/go/pkg/mod/github.com/gin-gonic/gin@v1.7.7/gin.go:511 (0x1687ab1)
(*Engine).ServeHTTP: engine.handleHTTPRequest(c)
/usr/local/go/src/net/http/server.go:2916 (0x129bf5a)
serverHandler.ServeHTTP: handler.ServeHTTP(rw, req)
/usr/local/go/src/net/http/server.go:1966 (0x1296f56)
(*conn).serve: serverHandler{c.server}.ServeHTTP(w, w.req)
/usr/local/go/src/runtime/asm_amd64.s:1571 (0x10648a0)
goexit: BYTE [=11=]x90 // NOP
然而,当我跟随tutorial时,一切都很好。这是我的代码:
package controllers
import (
"net/http"
"samzhangjy/go-blog/models"
"github.com/gin-gonic/gin"
)
type CreateBlogInput struct {
Title string `json:"title" binding:"required"`
Content string `json:"content" binding:"required"`
}
func CreateBlog(c *gin.Context) {
var input CreateBlogInput
if err := c.ShouldBindJSON(&input); err != nil {
c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{"error": err.Error()})
return
}
blog := models.Blog{Title: input.Title, Content: input.Content}
models.DB.Create(&blog)
c.JSON(http.StatusOK, gin.H{"data": blog})
}
func FindBlogs(c *gin.Context) {
var blogs []models.Blog
models.DB.Find(&blogs)
c.JSON(http.StatusOK, gin.H{"data": blogs})
}
func FindBlog(c *gin.Context) {
var blog models.Blog
if err := models.DB.First(&blog, "id = ?", c.Param("id")).Error; err != nil {
c.AbortWithStatusJSON(http.StatusNotFound, gin.H{"error": err.Error()})
return
}
c.JSON(http.StatusOK, gin.H{"data": blog})
}
type UpdateBlogInput struct {
Title string `json:"title"`
Content string `json:"content"`
}
func UpdateBlog(c *gin.Context) {
var blog models.Blog
if err := models.DB.Where("id = ?", c.Param("id")).First(&blog).Error; err != nil {
c.AbortWithStatusJSON(http.StatusNotFound, gin.H{"error": "record not found"})
return
}
var input UpdateBlogInput
if err := c.ShouldBindJSON(&input); err != nil {
c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{"error": err.Error()})
return
}
models.DB.Model(&blog).Updates(input)
c.JSON(http.StatusOK, gin.H{"data": blog})
}
我已阅读 ,但答案没有太大帮助。当我将空数据传递给控制器时,一切正常。但是如果我在请求正文中写一些要更新的东西,例如:
{ "title": "lorem ipsum" }
会崩溃并抛出上述异常
提前致谢!
更新:
我的以下模型:
package models
import "time"
type Blog struct {
ID uint `json:"id" gorm:"primary_key"`
Title string `json:"title"`
Content string `json:"content"`
CreatedAt time.Time `json:"created_at"`
}
可能是因为您使用的结构不同于 models.Blog 进行更新。您可以尝试以下操作吗:
func UpdateBlog(c *gin.Context) {
var blog models.Blog
if err := models.DB.Where("id = ?", c.Param("id")).First(&blog).Error; err != nil {
c.AbortWithStatusJSON(http.StatusNotFound, gin.H{"error": "record not found"})
return
}
var input UpdateBlogInput
if err := c.ShouldBindJSON(&input); err != nil {
c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{"error": err.Error()})
return
}
updateBlog := models.Blog{Title: input.Title, Content: input.Content}
models.DB.Model(&blog).Updates(&updateBlog)
c.JSON(http.StatusOK, gin.H{"data": updateBlog})
}
我正在尝试使用 Golang、Gin 和 GORM 构建一个简单的 CRUD 博客。但是,当我想更新博客内容时,触发了以下错误:
reflect: call of reflect.Value.SetString on uint Value
/usr/local/go/src/reflect/value.go:223 (0x10bfb25)
flag.mustBe: panic(&ValueError{methodName(), f.kind()})
/usr/local/go/src/reflect/value.go:2292 (0x10bfaa3)
Value.SetString: v.mustBe(String)
/Users/sam/go/pkg/mod/gorm.io/gorm@v1.23.5/schema/field.go:771 (0x144fcfc)
(*Field).setupValuerAndSetter.func11: field.ReflectValueOf(ctx, value).SetString(data)
/Users/sam/go/pkg/mod/gorm.io/gorm@v1.23.5/callbacks/update.go:144 (0x14b7d9a)
ConvertToAssignments.func2: field.Set(stmt.Context, stmt.ReflectValue, value)
/Users/sam/go/pkg/mod/gorm.io/gorm@v1.23.5/callbacks/update.go:275 (0x14b62fa)
ConvertToAssignments: assignValue(field, value)
/Users/sam/go/pkg/mod/gorm.io/gorm@v1.23.5/callbacks/update.go:73 (0x14b4fe4)
Update.func1: if set := ConvertToAssignments(db.Statement); len(set) != 0 {
/Users/sam/go/pkg/mod/gorm.io/gorm@v1.23.5/callbacks.go:130 (0x146d632)
(*processor).Execute: f(db)
/Users/sam/go/pkg/mod/gorm.io/gorm@v1.23.5/finisher_api.go:372 (0x1476811)
(*DB).Updates: return tx.callbacks.Update().Execute(tx)
/Volumes/Data/Develop/Go/go-blog/controllers/blog.go:65 (0x1693364)
UpdateBlog: models.DB.Model(&blog).Updates(input)
/Users/sam/go/pkg/mod/github.com/gin-gonic/gin@v1.7.7/context.go:168 (0x168a121)
(*Context).Next: c.handlers[c.index](c)
/Users/sam/go/pkg/mod/github.com/gin-gonic/gin@v1.7.7/recovery.go:99 (0x168a10c)
CustomRecoveryWithWriter.func1: c.Next()
/Users/sam/go/pkg/mod/github.com/gin-gonic/gin@v1.7.7/context.go:168 (0x1689246)
(*Context).Next: c.handlers[c.index](c)
/Users/sam/go/pkg/mod/github.com/gin-gonic/gin@v1.7.7/logger.go:241 (0x1689229)
LoggerWithConfig.func1: c.Next()
/Users/sam/go/pkg/mod/github.com/gin-gonic/gin@v1.7.7/context.go:168 (0x1688310)
(*Context).Next: c.handlers[c.index](c)
/Users/sam/go/pkg/mod/github.com/gin-gonic/gin@v1.7.7/gin.go:555 (0x1687f78)
(*Engine).handleHTTPRequest: c.Next()
/Users/sam/go/pkg/mod/github.com/gin-gonic/gin@v1.7.7/gin.go:511 (0x1687ab1)
(*Engine).ServeHTTP: engine.handleHTTPRequest(c)
/usr/local/go/src/net/http/server.go:2916 (0x129bf5a)
serverHandler.ServeHTTP: handler.ServeHTTP(rw, req)
/usr/local/go/src/net/http/server.go:1966 (0x1296f56)
(*conn).serve: serverHandler{c.server}.ServeHTTP(w, w.req)
/usr/local/go/src/runtime/asm_amd64.s:1571 (0x10648a0)
goexit: BYTE [=11=]x90 // NOP
然而,当我跟随tutorial时,一切都很好。这是我的代码:
package controllers
import (
"net/http"
"samzhangjy/go-blog/models"
"github.com/gin-gonic/gin"
)
type CreateBlogInput struct {
Title string `json:"title" binding:"required"`
Content string `json:"content" binding:"required"`
}
func CreateBlog(c *gin.Context) {
var input CreateBlogInput
if err := c.ShouldBindJSON(&input); err != nil {
c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{"error": err.Error()})
return
}
blog := models.Blog{Title: input.Title, Content: input.Content}
models.DB.Create(&blog)
c.JSON(http.StatusOK, gin.H{"data": blog})
}
func FindBlogs(c *gin.Context) {
var blogs []models.Blog
models.DB.Find(&blogs)
c.JSON(http.StatusOK, gin.H{"data": blogs})
}
func FindBlog(c *gin.Context) {
var blog models.Blog
if err := models.DB.First(&blog, "id = ?", c.Param("id")).Error; err != nil {
c.AbortWithStatusJSON(http.StatusNotFound, gin.H{"error": err.Error()})
return
}
c.JSON(http.StatusOK, gin.H{"data": blog})
}
type UpdateBlogInput struct {
Title string `json:"title"`
Content string `json:"content"`
}
func UpdateBlog(c *gin.Context) {
var blog models.Blog
if err := models.DB.Where("id = ?", c.Param("id")).First(&blog).Error; err != nil {
c.AbortWithStatusJSON(http.StatusNotFound, gin.H{"error": "record not found"})
return
}
var input UpdateBlogInput
if err := c.ShouldBindJSON(&input); err != nil {
c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{"error": err.Error()})
return
}
models.DB.Model(&blog).Updates(input)
c.JSON(http.StatusOK, gin.H{"data": blog})
}
我已阅读
{ "title": "lorem ipsum" }
会崩溃并抛出上述异常
提前致谢!
更新:
我的以下模型:
package models
import "time"
type Blog struct {
ID uint `json:"id" gorm:"primary_key"`
Title string `json:"title"`
Content string `json:"content"`
CreatedAt time.Time `json:"created_at"`
}
可能是因为您使用的结构不同于 models.Blog 进行更新。您可以尝试以下操作吗:
func UpdateBlog(c *gin.Context) {
var blog models.Blog
if err := models.DB.Where("id = ?", c.Param("id")).First(&blog).Error; err != nil {
c.AbortWithStatusJSON(http.StatusNotFound, gin.H{"error": "record not found"})
return
}
var input UpdateBlogInput
if err := c.ShouldBindJSON(&input); err != nil {
c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{"error": err.Error()})
return
}
updateBlog := models.Blog{Title: input.Title, Content: input.Content}
models.DB.Model(&blog).Updates(&updateBlog)
c.JSON(http.StatusOK, gin.H{"data": updateBlog})
}