Register a SA Forums Account here!
JOINING THE SA FORUMS WILL REMOVE THIS BIG AD, THE ANNOYING UNDERLINED ADS, AND STUPID INTERSTITIAL ADS!!!

You can: log in, read the tech support FAQ, or request your lost password. This dumb message (and those ads) will appear on every screen until you register! Get rid of this crap by registering your own SA Forums Account and joining roughly 150,000 Goons, for the one-time price of $9.95! We charge money because it costs us money per month for bills, and since we don't believe in showing ads to our users, we try to make the money back through forum registrations.
 
  • Locked thread
ChickenWing
Jul 22, 2010

:v:

functional programming thread died so this silly nonsense goes here because writing a megathread OP is :effort:

tl;dr goon new to scala seeks standard repository pattern layout that lets him run transactions at the service layer



I'm trying to rewrite the Play+Slick microservice I've been working on from a slapdash POC into something that adheres to bestbetter practices. Currently, the task is combining our DAOs into some semblance of an abstractable repository pattern that isn't miserable to write tests against.

Previously, we had each DAO define its own table+tablequery. In the case of tightly-related tables, one DAO would manage a handful of such. If a table was used in two different repositories, the table+tablequery would be redefined in the other class.

I've rejiggered this a little so that one class defines all of our tables and tablequeries, and also implements a base repository pattern. All the inheritors need to do is define their type (e.g. FooDao extends AbstractDao[Foo]) and override the abstract TableQuery val with their own (e.g. override def query: TableQuery[FooTable] = fooTableQuery (defined in AbstractDao))

In general, I'd assume that I should follow the usual repository pattern following this, i.e. keep everything in the DAO it's best related to, keep all the actual DB work hidden behind the scenes. I've just come on one little hitch with this - when I want a full service method to execute transactionally. Based on what I've read (not a lot, it doesn't seem like there's a ton of support community easily findable by way of google), it seems like either my DAOs are supposed to have dependencies on other services (seems weird as gently caress and I don't like it), or my repositories are only supposed to expose DBIOActions, and I'm actually supposed to run the queries at the service layer (seems even weirder?????????). My best idea so far has been to make a sort of Dao.runWithTransaction method that takes a list of functions, wraps them in DBIOActions, and runs them all. Not sure if that's a bit janky though

Is there an established pattern for this? Have I missed something dumb?

Adbot
ADBOT LOVES YOU

Volguus
Mar 3, 2009
Not functional programming per-se, but why not take a look at Spring Data, how they do it, how they define their repositories?

Personally, I am a fan of using an ORM, since I wrote a bazillion SQL queries before hibernate existed and I don't wanna do it again if I can help it. From an ORM perspective, there is no such thing as a "table". There is, however, the entity. The object. The thing you want to read/update/delete.
This can be in one table, in 100 tables or in the cloud. Nobody gives a gently caress, only the actual driver.

So, "tightly-related tables" presumably means relationships, one-to-many or many-to-many. If you still insist on using a DAO, then you normally load the main table records, and when the request comes for the children, load the children records (from presumably a different table). This is known as LAZY fetch in the ORM world, nothing new.

About transactions:
Your service will start a transaction, will call a bunch of DAO actions and your service will be responsible to call rollback if an exception occurs. Nobody else.

DONT THREAD ON ME
Oct 1, 2002

by Nyc_Tattoo
Floss Finder
I guess switching to doobie isn’t an option? Slick is horrible.

ChickenWing
Jul 22, 2010

:v:

Volguus posted:

Spring+orm

This is effectively what I'm trying to emulate. Slick is a query generator, so no ORM, but the repository pattern and service-boundary transactions are what I'm looking to emulate

MALE SHOEGAZE posted:

I guess switching to doobie isn’t an option? Slick is horrible.

Swapping libraries is a last resort sort of thing

Condiv
May 7, 2008

Sorry to undo the effort of paying a domestic abuser $10 to own this poster, but I am going to lose my dang mind if I keep seeing multiple posters who appear to be Baloogan.

With love,
a mod


DONT THREAD ON ME posted:

I guess switching to doobie isn’t an option? Slick is horrible.

what's your thoughts on quill? i've heard of doobie, and it seems interesting, but it's also deeper into functional territory than i'm used to at this point. also, how well does cats and friends work with intellij now?

  • Locked thread