【问题标题】:grails gorm cascading save best practicegrails gorm级联保存最佳实践
【发布时间】:2013-10-29 22:22:29
【问题描述】:

我有一些工作代码,但我对 GORM 和级联保存有点模糊。这是我的对象模型:

class Profile {
   PhotoAlbum photoAlbum

   static constraints = {
       photoAlbum(nullable:true)
   }
}

class PhotoAlbum {
   static hasMany = [photos:Photo]
   static belongsTo = [profile:Profile]
}

class Photo {
    static belongsTo = PhotoAlbum
}

这是我保存新照片对象的工作代码:

Photo photo = new Photo()

if (!profile.photoAlbum) { profile.photoAlbum = new PhotoAlbum(profile:profile) }

profile.photoAlbum.addToPhotos(photo)


if (!photo.save()) {
   def json = [
           status:'fail',
           message:messageSource.getMessage('label.photo.validate.failed.message', [photo.errorStrings].toArray(), LocaleContextHolder.locale)
   ]
   return json
}
if (!profile.photoAlbum.save()) {
   def json = [
           status:'fail',
           message:messageSource.getMessage('label.photo.validate.failed.message', [profile.photoAlbum.errorStrings].toArray(), LocaleContextHolder.locale)
   ]
   return json
}

if (!profile.save()) {
   def json = [
           status:'fail',
           message:messageSource.getMessage('label.photo.validate.failed.message', [profile.errorStrings].toArray(), LocaleContextHolder.locale)
   ]
   return json
}
else {
   def json = [
           status:'success',
           message:messageSource.getMessage('label.photo.insert.success.message', null, LocaleContextHolder.locale)
   ]
   return json
}

保存新照片对象似乎需要大量代码和错误检查。当我查看网站和书籍中的 grails 示例时,我没有看到很多错误检查。在我的情况下,如果无法保存照片,服务必须向客户端返回一个 json 错误字符串。我已经阅读了 GORM Gotchas 2 的帖子,但我仍然不清楚级联保存。

我确实发现,如果我不调用 photo.save() 和 profile.photoAlbum.save() 而只是调用 profile.save() 我会得到暂时的异常。所以我添加了 photo.save() 和 profile.photoAlbum.save() 以使一切正常。

【问题讨论】:

  • 仅供参考,将所有 save() 调用移至服务,或至少在 withTransaction { } 中。但最好有服务。

标签: grails grails-orm


【解决方案1】:

正如@Cregg 提到的,您应该将所有逻辑转移到服务中,以便在一个事务中处理对 DB 的所有调用。为了不得到瞬态异常,请尝试使用以下:

profile.save(flush: true, failOnError:true)

您应该创建ErrorController 来处理所有异常。见example

【讨论】:

  • flush:true 有效。我能够删除前 2 个 saves() 并最终得到 profile.save(flush:true) 和级联的保存。好的!作为旁注,我确实在服务中有这段代码。
猜你喜欢
  • 1970-01-01
  • 2014-11-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-10-18
  • 1970-01-01
  • 2014-05-08
  • 1970-01-01
相关资源
最近更新 更多