Slick Repo Methods All Participating in One Service Transaction

I currently have a set of data access objects called *SlickRepo . So, for example, UserSlickRepo , DistributionSlickRepo , ContentSlickRepo , etc.

Each of these Repositories has methods 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 at the service level, we have baked a repo in this 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) } } } 

Now we want createSomethingGood actually execute two repo methods in a transaction. Since all Slick content is locked in Slick replica methods, what's the best way to do this? I am not opposed to having Slick-specific code in my *ServiceImpl class (I mean weird but good), however that means I have to change the Repo classes to remove the code like getDatabase withDynSession all together and instead transfer in session from service level? For me it just seems ... wrong.

+8
scala
source share
2 answers

From my point of view, the correct approach is to add createSomething and createSomethingElse to the same transaction *Repo method ( SomethingRepo or SomethingElseRepo ) ( withTransaction {...} ). This is not a beautiful solution, but as simple as possible for me, because these entities are logically connected (which we can see from this code (dep.somethingRepo.createSomething, dep.somethingElseRepo.createSomethingElse) ). I believe that this is not a big violation for mixing operations on two objects in one DAO class. Please correct me if I am wrong.

+4
source share

Maybe there is another way. I have not tried it myself, but the idea is that you may have a session wrapper that is actually passed to the repository.

This shell should be created at the service level, but you can ignore the specific implementation on the companion object so that the service level does not actually concern Slick, but rather something like

 SessionWrapper.transactional: Session 

Hope this helps, I will add more answer if I get a change to try and try.

0
source share

All Articles