I try to migrate application to Slick 3.0. I would like to make a transaction for Slick 3.0. I know how to do it but I would like to ask for classes structure. Please take a look on sample repositories:
Some repositories (or DAO) for Slick 2.1:
class UserRepository {
def all()(implicit: Session): Seq[User] = users.run
def insert(user: User)(implicit: Session): Int = users.insert(user)
...
}
class CarRepository {
def all()(implicit: Session): Seq[Car] = cars.run
def insert(car: Car)(implicit: Session): Int = cars.insert(car)
...
}
In order to do the transaction in Slick 2.1 I could create a service where I can do the transaction:
db.withTransaction{ implicit session =>
userRepository.insert(user)
carRepository.insert(car)
}
so currently I have repositories (or DAOs) for database access and services for more general logic.
Some repositories (or DAO) for Slick 3.0:
class UserRepository {
def all(): Future[Seq[User]] = db.run(Users.result)
def insert(user: User): Future[Int] = db.run(Users += user)
...
}
class CarRepository {
def all(): Future[Seq[Car]] = db.run(Cars.result)
def insert(car: Car): Future[Int] = db.run(Cars += car)
...
}
In Slick 3.0 we can do the transaction on DBIOActions but when we have the structure as shown above it is not possible because of futures. I could create some UserCarRepository class to do the transaction but I think it is not the best one. In order to overcome that situation I expose DBIOActions in repositories (or DAOs) and then in other layer mix DBIOActions from User and Car repositories in one transaction to return Future at the end (next layer could be a service to operate on futures). When we have more repositories for transaction it could like a little bit messy.
How to structure this for Slick 3.0? How to gain more loose coupling for the transaction on different repositories?
Reading: https://github.com/playframework/play-slick/tree/master/samples https://github.com/slick/slick/issues/1084 https://groups.google.com/forum/#!topic/scalaquery/32cO7lHbxOs
A data access layer (DAL) in computer software is a layer of a computer program which provides simplified access to data stored in persistent storage of some kind, such as an entity-relational database. This acronym is prevalently used in Microsoft environments.
A Data-Access Layer (DAL) can support multiple databases, so the application is able to make use of any database as per its requirement. Because segregating the data access code, enables better maintainability and easy migration of the database.
Select your project in the VS Solution Explorer window and press CTRL+SHIFT+A to add a new item. Search for the ADO.NET Entity Data Model item, then click “Add” to proceed. After the ADO.NET Entity Data Model component is added, it will automatically pop up its Data Model Wizard.
Keep the inserts as DBIOActions as long as possible, compose them as needed and then do the actual DB-query. Sketch:
class UserRepository {
def all() = Users.result
def insert(user: User) = Users += user
...
}
class CarRepository {
def all() = Cars.result
def insert(car: Car) = Cars += car
...
}
val composedInserts = (for {
_ <- new UserRepository().insert(user)
_ <- new CarRepository().insert(car)
} yield ()).result
db.run(composedInserts.transactionally)
Edit: clarified message
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With