我有一个人表和动物表,在动物表中有对 personId 的 FK,因为它们之间存在一对多的关系。
我只想创建一个人并使用事务创建它的动物,因为我希望该过程是原子的(如果我无法创建它的动物,则数据库中没有使用人)
这是我如何接受人员创建请求的模型:
case class PersonCreateRequest(name: String, age: Int, animals: Seq[AnimalCreateRequest])
这就是数据库如何认识一个人:
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)
这就是数据库知道动物(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)
}
发生的事情是我只是没有得到响应......它继续处理而不返回任何内容或抛出错误