person テーブルと animal テーブルがあり、animal テーブルには personId への FK があります。これは、それらの間に 1 対多の関係があるためです。
プロセスをアトミックにしたいので、トランザクションを使用して人を作成し、その動物を作成したいだけです(動物を作成できなかった場合、データベースで人の使用はありません)
これは、人物作成リクエストを受け入れる方法のモデルです。
case class PersonCreateRequest(name: String, age: Int, animals: Seq[AnimalCreateRequest])
これは、DB が Person を認識する方法です。
case class Person(personId: Long, name, age: Int)
// this is just a companion object to help me take a PersonCreateRequest and make it Person
object Person {
def apply(person: PersonCreateRequest): Person = {
Person(0L,
person.name,
person.age)
}
}
私がアニマルと同じこと:
case class AnimalCreateRequest(animalType: String, age: Int)
これは、db が Animal(personId = owner) を認識する方法です。
case class Animal(animalId: Long, animalType: String, age: Int, personId: Long)
// here I need to get personId as parameter cause I will only have it after a person was created:
object Animal {
def apply(animal: AnimalCreateRequest, personId: Long): Animal = {
Animal(0L,
animal.animalType,
animal.age,
personId)
}
}
だから今、これは私がそれをやろうとした方法です(そして失敗しました):
lazy val ctx = new MysqlAsyncContext(CamelCase, "ctx")
import ctx._
def insertPerson(personToCreate: PersonCreateRequest): Future[Long] = {
// getting the person object that the db knows
val dbPerson = Person.apply(personToCreate)
// INSERT Person Query
val insertPersonQuery = quote {
query[Person].insert(lift(dbPerson)).returning(_.personId)
}
ctx.transaction { implicit ec =>
for {
personId <- ctx.run(insertPersonQuery)
contactIds <- {
Future.sequence(
personToCreate.animals.map(animal => {
val animalToInsert = Animal.apply(animal, personId)
insertAnimal(animalToInsert)
})
)
}
} yield personId
}
}
def insertAnimal(animal: Animal): Future[Long] = {
val q = quote {
query[Animal].insert(lift(animal)).returning(_.animalId)
}
ctx.run(q)
}
何が起こるかというと、応答が得られないということです...何も返さずに、またはエラーをスローせずに処理を続けます