Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Slick Repo methods all participating in one Service's Transaction

I currently have a set of Data Access Objects named with the convention *SlickRepo. So for instance, UserSlickRepo, DistributionSlickRepo, ContentSlickRepo, etc...

Each of these Repos have methods on them that basically follow this convention:

trait SomethingRepoImpl extends SomethingRepo {
  val somethingRepo: SomethingRepo = new SomethingRepoImpl

  class SomethingRepoImpl extends SomethingRepo with MySlickDatastore {

    def getSomething(id: UUID): Either[SomethingNotFoundError, Something] = {
      getDatabase withDynSession {
        // Slick stuff
      }
    }
    def createSomething .....
  }
}

Now up at a Service level, we bake in this repo class and we have methods that look like this:

trait SomethingServiceImpl extends SomethingService {

  dep: SomethingRepo with SomethingElseRepo =>


  val somethingService = new SomethingServiceImpl

  class SomethingServiceImpl extends SomethingService {

    def createSomethingGood(): Either[SomeError, (Something, SomethingElse)] = {
      (dep.somethingRepo.createSomething, dep.somethingElseRepo.createSomethingElse)
    }

  }
}

We now desire to have createSomethingGood actually run the two repo methods within a transaction. Since all the Slick stuff is locked up in the Slick specific Repo methods, what's the best way to do this? I'm not opposed to having Slick-specific code in my *ServiceImpl classes (I mean weird, but ok), however does that mean I have to change my Repo classes to remove the getDatabase withDynSession type code all together and instead pass in a session from the service layer? To me, that just seems... wrong.

like image 736
ThaDon Avatar asked Jun 22 '15 18:06

ThaDon


1 Answers

From my point of view the right approach is to add createSomething and createSomethingElse to one *Repo (SomethingRepo or SomethingElseRepo) transactional method (withTransaction {...}). It's not a beautiful solution but as simple as possible for me and because these entities are logically connected (which we can see from this code (dep.somethingRepo.createSomething, dep.somethingElseRepo.createSomethingElse)) I think it's not a big violation to mix operation on 2 entities in one DAO class. Please, fix me, if I'm wrong.

like image 134
ka4eli Avatar answered Nov 15 '22 06:11

ka4eli