【发布时间】:2014-01-22 18:38:02
【问题描述】:
我有一个类,DigitalObject,它基本上是一个 url 和上次修改日期的容器。
class DigitalObject {
String url
Date lastUpdated
}
我有两个类使用 DigitalObjects 来引用与其相关的不同 url
class Video {
DigitalObject englishVersion
DigitalObject frenchVersion
}
class Image {
DigitalObject thumbnailImage
DigitalObject fullSizeImage
}
我在正确映射时遇到了很多麻烦。
我希望能够删除一个 DigitalObject 并让 GORM 负责将其从其父级中删除。
如果我在尝试删除 digitalObject 时将其保留为上述方式,则会违反外键约束。
如果我在父端添加 hasOne 映射,我会收到一条错误消息,指出要指定关系的另一端,但我不清楚在哪里执行此操作,因为 DigitalObject 可以属于图像或视频。像这样。
class Video {
static hasOne = [englishVersion: DigitalObject, frenchVersion: DigitalObject]
}
在子类中添加belongsTo会导致同样的外键约束错误。像这样。
class DigitalObject {
String url
Date lastUpdated
static belongsTo = [Image, Video]
}
我将不得不放弃并手动将其从其父级中删除吗?
在此先感谢您的帮助,如果此问题得到解答,我深表歉意,尽管我确信这不可能不常见的用例。
2014 年 1 月 24 日编辑
尝试 Andrew 的建议,我的实际域类比我使用的示例复杂得多,因此我的 beforeDelete() 最终如下所示,这非常难看,可能很难维护。
def beforeDelete() {
DigitalObject.withNewSession {
def imageThumbnailImages = Image.findAllByThumbnailImage(this)
if (imageThumbnailImages) {
imageThumbnailImages.each { image ->
image.thumbnailImage = null
image.save(flush: true)
}
}
def imagePreviewImages = Image.findAllByPreviewImage(this)
if (imagePreviewImages) {
imagePreviewImages.each { image ->
image.previewImage = null
image.save(flush: true)
}
}
def imageFullImages = Image.findAllByFullImage(this)
if (imageFullImages) {
imageFullImages.each { image ->
image.fullImage = null
image.save(flush: true)
}
}
def videoThumbnailImages = Video.findAllByThumbnailImage(this)
if (videoThumbnailImages) {
videoThumbnailImages.each { image ->
image.thumbnailImage = null
image.save(flush: true)
}
}
def videoPreviewImages = Video.findAllByPreviewImage(this)
if (videoPreviewImages) {
videoPreviewImages.each { image ->
image.previewImage = null
image.save(flush: true)
}
}
def videoFullVideosEng = Video.findAllByFullVideoEng(this)
if (videoFullVideosEng) {
videoFullVideosEng.each { video ->
video.fullVideoEng = null
video.save(flush: true)
}
}
def videoFullVideosFra = Video.findAllByFullVideoFra(this)
if (videoFullVideosFra) {
videoFullVideosFra.each { video ->
video.fullVideoFra = null
video.save(flush: true)
}
}
def captionsEngVideos = Video.findAllByCaptionsEng(this)
if (captionsEngVideos) {
captionsEngVideos.each { videos ->
videos.captionsEng = null
videos.save(flush: true)
}
}
def captionsFraVideos = Video.findAllByCaptionsFra(this)
if (captionsFraVideos) {
captionsFraVideos.each { video ->
video.captionsFra = null
video.save(flush: true)
}
}
def signLanguageEngVideos = Video.findAllBySignLanguageEng(this)
if (signLanguageEngVideos) {
signLanguageEngVideos.each { video ->
video.signLanguageEng = null
video.save(flush: true)
}
}
def signLanguageFraVideos = Video.findAllBySignLanguageEng(this)
if (signLanguageFraVideos) {
signLanguageFraVideos.each { video ->
video.signLanguageFra = null
video.save(flush: true)
}
}
}
【问题讨论】:
-
这不完全是您所追求的,但一个快速(且未经测试)的想法是将
beforeDelete处理程序添加到DigitalObjcet(使用您的原始类定义)。处理程序可以找到所有父对象(使用您最喜欢的 GORM 查询风格)并清空(?)相关的DigitalObject引用。 -
已根据您的建议使用 beforeDelete() 示例编辑问题。虽然它有效并且是我目前唯一有效的解决方案,但我希望有更好的方法来做到这一点。
-
是的,当然是一种繁琐的方法。我想知道您是否会发现调整整体模型更容易?也许像将
type(可能还有language)限定符添加到DigitalObject,将对象指定为预览、缩略图等简单的事情。然后,Image和Video可以保存一个简单的集合. -
由于该模型不属于我,而且我的项目不是唯一使用它的项目,因此我犹豫是否要进行如此剧烈的更改。我在下面提供了我的解决方案,可能不是最好的方法,但在这种情况下我可以开始工作的最好方法。
标签: grails grails-orm grails-2.0 grails-domain-class