4

I have model repository class with byId and save metdhods

def byID(id:Long) = db.run{ query.filter(_.id === id).result }.map(_.headOption)
def save(model:User) = db.run{ query.filter(_.id===model.id).update(model) }

Now I want to use both these methods, first load user, then change something, and then save user, like this

userRepository.byID(5L).map{_.map{user =>
  val newuser = user.copy(name = "John")
  userRepository.save(newuser)            
}}

How can I do it in one transaction?

Aldo Stracquadanio
  • 6,167
  • 1
  • 23
  • 34
codez
  • 1,381
  • 1
  • 18
  • 28

1 Answers1

1

I think that slick 3 doesn't support having a transaction that spans over different futures and when you call db.run you are passing in a DBIO[SomeType] in and getting a Future out. The good news is that you can instead compose your DBIOs structuring your API in a slightly different way:

def byID(id:Long) = query.filter(_.id === id).result }.map(_.headOption)
def save(model:User) = query.filter(_.id===model.id).update(model)

And then:

db.run(userRepository.byID(5L).flatMap { users => 
  DBIO.sequence(users.map { user =>
    userRepository.save(user.copy(name = "John"))            
  })
}.transactionally)
Aldo Stracquadanio
  • 6,167
  • 1
  • 23
  • 34