我有一个类,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日编辑
尝试安德鲁的建议,我的实际域类比我使用的例子复杂得多,因此我的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)
}
}
}
答案 0 :(得分:1)
我有一个类似的域类,可以由不同的父级拥有,我的级联删除按预期工作。所以使用你的课程,你试过这个:
class DigitalObject {
String url
Date lastUpdated
Image image
Video video
static belongsTo = [
image: Image,
video: Video
]
编辑:从下面的约束中删除了方括号!
static constraints = {
image( nullable : true )
video( nullable : true )
}
}
不确定您的图像/视频上是否还有onOne。但尝试使用和不使用。
答案 1 :(得分:0)
这很丑陋,可能不是最好的方法,但因为我无法让其他方法建议可靠地工作,并且由于我想尽可能对域类进行最小的更改,因为我的project并不是唯一使用它们的人。
我将以下方法添加到我的DigitalObjectController。
def deleteFromMediaAsset(Long id, String parentClass, String parentProperty, String parentId) {
def digitalObjectInstance = DigitalObject.get(id)
if (!digitalObjectInstance) {
flash.message = message(code: 'default.not.found.message', args: [
message(code: 'digitalObject.label', default: 'DigitalObject'),
id
])
redirect(controller: parentClass, action: 'edit', id: parentId)
return
}
try {
def classOfParent = grailsApplication.domainClasses.find {
it.clazz.simpleName == parentClass.capitalize()
}.clazz
def parentInstance = classOfParent.get(parentId)
parentInstance.setProperty(parentProperty, null)
digitalObjectInstance.delete(flush: true)
flash.message = message(code: 'default.deleted.message', args: [
message(code: 'digitalObject.label', default: 'DigitalObject'),
id
])
redirect(controller: parentClass, action: 'edit', id: parentId)
}
catch (DataIntegrityViolationException e) {
flash.message = message(code: 'default.not.deleted.message', args: [
message(code: 'digitalObject.label', default: 'DigitalObject'),
id
])
redirect(controller: parentClass, action: 'edit', id: parentId)
}
}
基本上我传递父Image或Video类和ID以及DigitalObject引用的属性和我想删除的DigialObject的ID。我在父对象上将属性设置为null,然后删除DigitalObject。
丑陋但它现在有效,祝我好运。