functional programming thread died so this silly nonsense goes here because writing a megathread OP is 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 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?
|
|
# ? Jul 27, 2018 21:18 |
|
|
# ? May 5, 2024 20:30 |
|
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.
|
# ? Jul 28, 2018 03:15 |
|
I guess switching to doobie isn’t an option? Slick is horrible.
|
# ? Jul 28, 2018 18:34 |
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
|
|
# ? Jul 28, 2018 20:42 |
|
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?
|
# ? Sep 8, 2018 01:16 |