我有一个在我的对象图保存不正确的级联一些奇怪的行为。 或许这是与嵌套事务,但也许不是。
下面是我的3个领域类:
Station.groovy
class Station {
/** Dependency injected {@link de.hutapp.tapandknow.system.SettingsService}.*/
def settingsService
static hasMany = [localizedStations: LocalizedStation,
stationIdentifiers: AbstractStationIdentifier]
}
LocalizedStation.groovy
class LocalizedStation {
/** Delete-cascade from the {@link Station} parent. */
static belongsTo = [station : Station]
/** An image that represents the LocalizedStation. */
MediaFile headerImage
/** The articles inside this LocalizedStation .*/
List<Article> articles
static hasMany = [articles: Article]
static mapping = {
headerImage cascade: 'all'
articles cascade: 'all-delete-orphan'
}
}
MediaFile.groovy
class MediaFile {
/* some basic properties here*/
static constraints = {
name blank: false
originalFilename blank: false
description blank: false
}
def beforeDelete() {
// delete the associated file
new File(getFileLocation()).delete()
}
}
所以对象图是站 - > LocalizedStation->媒体文件
我保存/更新下列服务方法的对象:
StationService.groovy
@Transactional
class StationService {
def mediaFileService
/**
* Creates a new {@link Station} and saves it.
* @return The newly created {@link Station} instance.
*/
Station createStation(LocalizedStation localizedStationInstance, InputStream headerImage, String originalFilename) {
localizedStationInstance = updateLocalizedStation(localizedStationInstance, headerImage, originalFilename)
Station stationInstance = new Station()
stationInstance.addToLocalizedStations(localizedStationInstance)
stationInstance.save()
stationInstance.localizedStations[0].headerImage.save() // TODO: check why this is necessary
return stationInstance
}
LocalizedStation updateLocalizedStation(LocalizedStation localizedStationInstance, InputStream headerSource, String originalFilename) {
if (headerSource) {
MediaFile headerFile = mediaFileService.createMediaFile(headerSource, originalFilename, "foobar") // TODO: add description
localizedStationInstance.headerImage = headerFile
}
localizedStationInstance.save()
return localizedStationInstance
}
}
MediaFileService.groovy
@Transactional
class MediaFileService {
MediaFile createMediaFile(InputStream input, String originalFilename, String description) {
MediaFile mediaFileInstance = new MediaFile(
name: originalFilename,
description: description)
mediaFileInstance.save(flush: true) // flush for id
mediaFileInstance.storeMediaFile(input, originalFilename)
mediaFileInstance.save()
return mediaFileInstance
}
}
正如你所看到的,如果我叫stationService.createStation(),我必须手动保存媒体文件,即在LocalizedStation挂起。 这只是如果我叫createStation(),它本身调用updateLocalizedStation()发生。 然后媒体文件将不被坚持,除非我明确地保存它createStation()。
如果我直接调用updateLocalizedStation(),一切正常。
任何意见或建议?
更新:
这个问题dissappears,如果我添加@Transactional(传播= Propagation.REQUIRES_NEW)到createMediaFile()方法。
据我了解的文档,这将创建一个新的事务。 但是,这是不是真的我想要的,我想要一个交易,跨越所有方法。