【问题标题】:grails: dont save similar domain object again, use present objectgrails:不要再次保存类似的域对象,使用当前对象
【发布时间】:2014-09-08 22:58:17
【问题描述】:

问题:
我有“路由”域,它有站点(域)。
如果我保存路线,我也应该保存站点。 (使用级联:'all' 映射)
但是,如果数据库中已经存在同名的站,我想使用它,不再创建这样的站。
所以我保存的路线必须只保存新站点。

示例:
域名:

class Route {
    String name
    List<Station> stations

    static mapping = {
        stations cascade: 'all', lazy: false
    }
    static hasMany = [
        stations: Station
    ]
}

class Station {
   String name
}

控制器/服务:

def route = new Route()
route.stations.add(new Station("stationOne"))
route.stations.add(new Station("stationTwo"))
route.save()
//now in db there are 2 stations. 

//now create new route with 2 stations, with one similar to already saved ('stationOne').
def route2 = new Route()
route2.stations.add(new Station("stationOne")) //<-- this one i want to be replaced
                                               // with the inDB one, if i save the route
                                               // in DB must be only one "stationOne"
                                               // and every route must point to it,
                                               // not own "stationOne", if the route saved
route2.stations.add(new Station("stationThree"))

route2.save()
//now i wish in DB there are only 3 stations.
//and route2 has both from DB. And the reference (in list) from route2 to "stationOne"
//inMemory object is now replaced with reference to inDB station object.

我可以编写代码,例如“replaceWithDBStationReferences(route)”
但是我的项目足够大,可以在代码中测试这些东西。
是否可以在域中的某个地方定义它?或任何其他解决方案?

【问题讨论】:

  • 你能发布你的代码吗?
  • 已添加。但在这个问题中,我只想知道“如何”的最佳实践和可能的解决方案。

标签: grails grails-orm


【解决方案1】:

您可以使用findOrCreate 动态方法:

route2.stations.add(Station.findOrCreateByName("stationOne"))

findOrCreateByNamefindByName 类似,除了普通查找器将返回 null(如果没有找到),findOrCreate 将根据查询参数创建一个新的瞬态实例,在本例中为 new Station(name:'stationOne') .

还有findOrSaveBy... 做同样的事情,但在返回之前保存新实例。

【讨论】:

  • 它不完全是我要找的东西,但是好的,如果不在域中,比这种方式要好得多:)
【解决方案2】:

如果您需要使用数据库中的现有 Route,您只需先获取它即可。像这样的:

def route = Route.findByName(name)
def stations = getNewAndModifiedStations()
stations.each { station ->
   def existingStation = route.stations.find { station.name?.equals(it.name) }
   if (existingStation) {
   // if station is found
       existingStation.updateProperties(station)
   } else {
     // new station here
     route.stations.add(station)
   }
}

route.save()

【讨论】:

  • 我需要现有的电台。如果我调用 route.save() 它会再次保存车站.. 我需要像 || 这样的东西站级联:“不要保存存在的站,用数据库中已经存在的替换对它的引用”||我应该在代码中测试每条路线,如果车站存在,并手动替换参考,而不是保存路线?
  • 我认为我的问题描述得不够好。所以我更新了这个问题,以确保我想知道什么。
猜你喜欢
  • 2015-01-06
  • 2014-06-04
  • 2014-06-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-12-06
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多