Grails的2.4.2:奇怪的级联保存在嵌套事务行为(Grails 2.4.2: Strange

2019-10-20 10:34发布

我有一个在我的对象图保存不正确的级联一些奇怪的行为。 或许这是与嵌套事务,但也许不是。

下面是我的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()方法。

据我了解的文档,这将创建一个新的事务。 但是,这是不是真的我想要的,我想要一个交易,跨越所有方法。

文章来源: Grails 2.4.2: Strange cascading save behaviour in nested transactions