Scala播放slick db错误

时间:2018-07-03 19:08:06

标签: scala playframework sbt slick

我正在测试Slick数据库框架。

我有一个人员和地址数据库模型,一个具有基本CRUD操作的存储库和一个人员控制器。

数据模型:

package person

import java.util.concurrent.atomic.AtomicLong

import play.api.libs.json.Json

case class Address(id: Option[Int] = None, country: String, state: String, city: String, street: String, street_number: Int, extra_info: String)

case class Person(id: Option[Int] = None, name: String, last_name: String, address_id: Int)

object Address {
  implicit val addressFormat = Json.format[Address]
}

object Person {
  implicit val personFormat = Json.format[Person]
}

人员资料库:

package person

import javax.inject.Inject
import play.api.db.slick.DatabaseConfigProvider
import slick.jdbc.JdbcProfile

import scala.concurrent.{ExecutionContext, Future}

class PersonRepository @Inject() (dbConfigProvider: DatabaseConfigProvider)(implicit ec: ExecutionContext) {
  // We want the JdbcProfile for this provider
  val dbConfig = dbConfigProvider.get[JdbcProfile]

  // These imports are important, the first one brings db into scope, which will let you do the actual db operations.
  // The second one brings the Slick DSL into scope, which lets you define the table and other queries.
  import dbConfig._
  import profile.api._

  class AddressTable(tag: Tag) extends Table[Address](tag, "addresses") {

    def id = column[Int]("id", O.PrimaryKey, O.AutoInc)

    def country = column[String]("country")

    def state = column[String]("state")

    def city = column[String]("city")

    def street = column[String]("street")

    def street_number = column[Int]("street_number")

    def extra_info = column[String]("extra_info")

    override def * = (id.?, country, state, city, street, street_number, extra_info) <> ((Address.apply _).tupled, Address.unapply)
  }

  private val addresses = TableQuery[AddressTable]


  class PeopleTable(tag: Tag) extends Table[Person](tag, "people") {

    def id = column[Int]("id", O.PrimaryKey, O.AutoInc)

    def name = column[String]("first_name")

    def last_name = column[String]("last_name")

    def address_id = column[Int]("address_id")

    def address = foreignKey("address_id", address_id, addresses)(_.id)

    override def * = (id.?, name, last_name, address_id) <> ((Person.apply _).tupled, Person.unapply)
  }

  /**
    * The starting point for all queries on the people table.
    */
  private val people = TableQuery[PeopleTable]

  def get(id: Int) = db.run((for (person <- people if person.id === id) yield person).result.headOption)

  def update(person: Person): Future[Int] = db.run(people.filter(_.id === person.id).update(person))

  def delete(id: Int): Future[Int] = db.run(people.filter(_.id === id).delete)

  def list(): Future[Seq[Person]] = db.run (people.result)

  def add(user: Person) = db
    .run(people returning people.map(_.id) += user)
    .map(id => user.copy(id = Some(id)))
}

人员控制器:

package person

import javax.inject.Inject
import play.api.mvc._
import play.api.libs.json.{JsError, Json, Reads}

import scala.concurrent.ExecutionContext

class PersonController @Inject()(repo: PersonRepository, cc: ControllerComponents)(implicit ec: ExecutionContext) extends AbstractController(cc) {

   /*This helper parses and validates JSON using the implicit `personReads`
   above, returning errors if the parsed json fails validation.*/
  def validateJson[A: Reads] = parse.json.validate(
    _.validate[A].asEither.left.map(e => BadRequest(JsError.toJson(e)))
  )


  def list = Action.async { implicit request =>
    repo.list().map { people =>
      Ok(Json.toJson(people))
    }
  }

  def get(id: Int) = Action.async {
    implicit request => {
      val person = repo.get(id)
      person.map {
        case Some(p) => Ok(Json.toJson(p))
        case None => NotFound
      }.recover { case ex => Conflict("Fail: " + ex.toString) }
    }
  }


  def add() = Action(validateJson[Person]).async {
    implicit request => {
      val person = request.body
      repo.add(person).map {
        p => Ok(Json.toJson(p))
      }.recover { case ex => Conflict("Fail: " + ex.toString) }
    }
  }


  def update(id_new: Int) = Action(validateJson[Person]).async {
    implicit request => {
      val person = request.body.copy(id = Some(id_new))
      repo.update(person).map {
        p => Ok("Updated user of id: " + p)
      }.recover { case ex => Conflict("Fail: "+ ex.toString) }
    }
  }

  def delete(id: Int) = Action {
    implicit request => {
      repo.delete(id)
      Ok("Deleted")
    }
  }

}

application.conf

db {
  slick.dbs.default.driver = "slick.driver.MySQLDriver$"
  slick.dbs.default.db.driver = "com.mysql.jdbc.Driver"
  slick.dbs.default.db.url = "jdbc:mysql://localhost/3306/test"
  slick.dbs.default.db.user = "root"
  slick.dbs.default.db.password = "root1234"
}

问题是我收到此错误,但我不知道它来自哪里。 DB conf中似乎有问题

[error] application - 

! @78en3p1cm - Internal server error, for (GET) [/] ->

play.api.UnexpectedException: Unexpected exception[CreationException: Unable to create injector, see the following errors:

1) No implementation for play.api.db.slick.DatabaseConfigProvider was bound.
  while locating play.api.db.slick.DatabaseConfigProvider
    for the 1st parameter of person.PersonRepository.<init>(PersonRepository.scala:9)
  while locating person.PersonRepository
    for the 1st parameter of person.PersonController.<init>(PersonController.scala:9)
  while locating person.PersonController
    for the 3rd parameter of router.Routes.<init>(Routes.scala:33)
  at play.api.inject.RoutesProvider$.bindingsFromConfiguration(BuiltinModule.scala:121):
Binding(class router.Routes to self) (via modules: com.google.inject.util.Modules$OverrideModule -> play.api.inject.guice.GuiceableModuleConversions$$anon$1)

1 error]
    at play.core.server.DevServerStart$$anon$1.reload(DevServerStart.scala:186)
    at play.core.server.DevServerStart$$anon$1.get(DevServerStart.scala:124)
    at play.core.server.AkkaHttpServer.handleRequest(AkkaHttpServer.scala:222)
    at play.core.server.AkkaHttpServer.$anonfun$createServerBinding$1(AkkaHttpServer.scala:137)
    at akka.stream.impl.fusing.MapAsync$$anon$25.onPush(Ops.scala:1194)
    at akka.stream.impl.fusing.GraphInterpreter.processPush(GraphInterpreter.scala:519)
    at akka.stream.impl.fusing.GraphInterpreter.processEvent(GraphInterpreter.scala:482)
    at akka.stream.impl.fusing.GraphInterpreter.execute(GraphInterpreter.scala:378)
    at akka.stream.impl.fusing.GraphInterpreterShell.runBatch(ActorGraphInterpreter.scala:585)
    at akka.stream.impl.fusing.GraphInterpreterShell$AsyncInput.execute(ActorGraphInterpreter.scala:469)
Caused by: com.google.inject.CreationException: Unable to create injector, see the following errors:

1) No implementation for play.api.db.slick.DatabaseConfigProvider was bound.
  while locating play.api.db.slick.DatabaseConfigProvider
    for the 1st parameter of person.PersonRepository.<init>(PersonRepository.scala:9)
  while locating person.PersonRepository
    for the 1st parameter of person.PersonController.<init>(PersonController.scala:9)
  while locating person.PersonController
    for the 3rd parameter of router.Routes.<init>(Routes.scala:33)
  at play.api.inject.RoutesProvider$.bindingsFromConfiguration(BuiltinModule.scala:121):
Binding(class router.Routes to self) (via modules: com.google.inject.util.Modules$OverrideModule -> play.api.inject.guice.GuiceableModuleConversions$$anon$1)

1 error
    at com.google.inject.internal.Errors.throwCreationExceptionIfErrorsExist(Errors.java:470)
    at com.google.inject.internal.InternalInjectorCreator.initializeStatically(InternalInjectorCreator.java:155)
    at com.google.inject.internal.InternalInjectorCreator.build(InternalInjectorCreator.java:107)
    at com.google.inject.Guice.createInjector(Guice.java:99)
    at com.google.inject.Guice.createInjector(Guice.java:84)
    at play.api.inject.guice.GuiceBuilder.injector(GuiceInjectorBuilder.scala:185)
    at play.api.inject.guice.GuiceApplicationBuilder.build(GuiceApplicationBuilder.scala:137)
    at play.api.inject.guice.GuiceApplicationLoader.load(GuiceApplicationLoader.scala:21)
    at play.core.server.DevServerStart$$anon$1.$anonfun$reload$3(DevServerStart.scala:174)
    at play.utils.Threads$.withContextClassLoader(Threads.scala:21)
[error] application - 

! @78en3p1cm - Internal server error, for (GET) [/favicon.ico] ->

play.api.UnexpectedException: Unexpected exception[CreationException: Unable to create injector, see the following errors:

1) No implementation for play.api.db.slick.DatabaseConfigProvider was bound.
  while locating play.api.db.slick.DatabaseConfigProvider
    for the 1st parameter of person.PersonRepository.<init>(PersonRepository.scala:9)
  while locating person.PersonRepository
    for the 1st parameter of person.PersonController.<init>(PersonController.scala:9)
  while locating person.PersonController
    for the 3rd parameter of router.Routes.<init>(Routes.scala:33)
  at play.api.inject.RoutesProvider$.bindingsFromConfiguration(BuiltinModule.scala:121):
Binding(class router.Routes to self) (via modules: com.google.inject.util.Modules$OverrideModule -> play.api.inject.guice.GuiceableModuleConversions$$anon$1)

1 error]
    at play.core.server.DevServerStart$$anon$1.reload(DevServerStart.scala:186)
    at play.core.server.DevServerStart$$anon$1.get(DevServerStart.scala:124)
    at play.core.server.AkkaHttpServer.handleRequest(AkkaHttpServer.scala:222)
    at play.core.server.AkkaHttpServer.$anonfun$createServerBinding$1(AkkaHttpServer.scala:137)
    at akka.stream.impl.fusing.MapAsync$$anon$25.onPush(Ops.scala:1194)
    at akka.stream.impl.fusing.GraphInterpreter.processPush(GraphInterpreter.scala:519)
    at akka.stream.impl.fusing.GraphInterpreter.processEvent(GraphInterpreter.scala:482)
    at akka.stream.impl.fusing.GraphInterpreter.execute(GraphInterpreter.scala:378)
    at akka.stream.impl.fusing.GraphInterpreterShell.runBatch(ActorGraphInterpreter.scala:585)
    at akka.stream.impl.fusing.GraphInterpreterShell$AsyncInput.execute(ActorGraphInterpreter.scala:469)
Caused by: com.google.inject.CreationException: Unable to create injector, see the following errors:

1) No implementation for play.api.db.slick.DatabaseConfigProvider was bound.
  while locating play.api.db.slick.DatabaseConfigProvider
    for the 1st parameter of person.PersonRepository.<init>(PersonRepository.scala:9)
  while locating person.PersonRepository
    for the 1st parameter of person.PersonController.<init>(PersonController.scala:9)
  while locating person.PersonController
    for the 3rd parameter of router.Routes.<init>(Routes.scala:33)
  at play.api.inject.RoutesProvider$.bindingsFromConfiguration(BuiltinModule.scala:121):
Binding(class router.Routes to self) (via modules: com.google.inject.util.Modules$OverrideModule -> play.api.inject.guice.GuiceableModuleConversions$$anon$1)

1 error
    at com.google.inject.internal.Errors.throwCreationExceptionIfErrorsExist(Errors.java:470)
    at com.google.inject.internal.InternalInjectorCreator.initializeStatically(InternalInjectorCreator.java:155)
    at com.google.inject.internal.InternalInjectorCreator.build(InternalInjectorCreator.java:107)
    at com.google.inject.Guice.createInjector(Guice.java:99)
    at com.google.inject.Guice.createInjector(Guice.java:84)
    at play.api.inject.guice.GuiceBuilder.injector(GuiceInjectorBuilder.scala:185)
    at play.api.inject.guice.GuiceApplicationBuilder.build(GuiceApplicationBuilder.scala:137)
    at play.api.inject.guice.GuiceApplicationLoader.load(GuiceApplicationLoader.scala:21)
    at play.core.server.DevServerStart$$anon$1.$anonfun$reload$3(DevServerStart.scala:174)
    at play.utils.Threads$.withContextClassLoader(Threads.scala:21)

0 个答案:

没有答案