我在playframework scala环境中收到这个错误,这些课程已经公开了,请看下面的内容。我是否也可以直接调用AbstractBaseDAO,因为它是一个特征,这是基于激活器模板的示例代码。但错误只发生在我的代码上。
ProvisionException: Unable to provision, see the following errors:
1) No implementation for models.daos.AbstractBaseDAO<models.persistence.SlickTables$CategoriesTable, models.entities.Category> was bound.
while locating models.daos.AbstractBaseDAO<models.persistence.SlickTables$CategoriesTable, models.entities.Category> for parameter 0 at
controllers.CategoryController.<init>(CategoryController.scala:12)
while locating controllers.CategoryController for parameter 2 at router.Routes.<init>(Routes.scala:35)
while locating router.Routes while locating play.api.inject.RoutesProvider while locating play.api.routing.Router for parameter 0 at play.api.http.JavaCompatibleHttpRequestHandler.<init>(HttpRequestHandler.scala:200)
while locating play.api.http.JavaCompatibleHttpRequestHandler while locating play.api.http.HttpRequestHandler for parameter 4 at
play.api.DefaultApplication.<init>(Application.scala:220) at play.api.DefaultApplication.class(Application.scala:220)
while locating play.api.DefaultApplication
while locating play.api.Application
- SlickTables.scala ------------
package models.persistence
import models.entities.Supplier
import models.entities.Category
import models.entities.Product
import play.api.Play
import play.api.db.slick.{DatabaseConfigProvider, HasDatabaseConfig}
import slick.driver.JdbcProfile
/**
* The companion object.
*/
object SlickTables extends HasDatabaseConfig[JdbcProfile] {
protected lazy val dbConfig = DatabaseConfigProvider.get[JdbcProfile](Play.current)
import dbConfig.driver.api._
abstract class BaseTable[T](tag: Tag, name: String) extends Table[T](tag, name) {
def id = column[Long]("id", O.PrimaryKey, O.AutoInc)
}
case class SimpleSupplier(name: String, desc: String)
class SuppliersTable(tag: Tag) extends BaseTable[Supplier](tag, "suppliers") {
def name = column[String]("name")
def desc = column[String]("desc")
def * = (id, name, desc) <> (Supplier.tupled, Supplier.unapply)
}
val suppliersTableQ : TableQuery[SuppliersTable] = TableQuery[SuppliersTable]
class CategoriesTable(tag: Tag) extends BaseTable[Category](tag, "categories") {
def name = column[String]("name")
def description = column[String]("description")
def parent_id = column[Long]("parent_id")
def * = (id, name, description, parent_id) <> (Category.tupled, Category.unapply)
}
val categoriesTableQ : TableQuery[CategoriesTable] = TableQuery[CategoriesTable]
class ProductsTable(tag: Tag) extends BaseTable[Product](tag, "products") {
def name = column[String]("name")
def code = column[String]("code")
def description = column[String]("description")
def price = column[Double]("price")
def keywords = column[String]("keywords")
def image = column[String]("image")
def category = column[Long]("category_id")
def state = column[String]("state")
def limitsell = column[Int]("limitsell")
def * = (id, name, code, description, price, keywords, image, category, state, limitsell) <> (Product.tupled, Product.unapply)
}
val productsTableQ : TableQuery[ProductsTable] = TableQuery[ProductsTable]
}
- CategoryController.scala -----------------
package controllers
import javax.inject._
import models.daos.{AbstractBaseDAO, BaseDAO}
import models.entities.Category
import models.persistence.SlickTables.CategoriesTable
import play.api.libs.json.{Json, Writes}
import play.api.mvc._
import scala.concurrent.{Future, ExecutionContext}
/*
line 12 is after the singleton anotation
*/
@Singleton
class CategoryController @Inject()(categoriesDAO : AbstractBaseDAO[CategoriesTable,Category])(implicit exec: ExecutionContext) extends Controller {
implicit val categoryWrites = new Writes[Category] {
def writes(sup: Category) = Json.obj(
"id" -> sup.id,
"name" -> sup.name,
"description" -> sup.description,
"parent_id" -> sup.parent_id
)
}
def category(id : Long) = Action.async {
categoriesDAO.findById(id) map { sup => sup.fold(NoContent)(sup => Ok(Json.toJson(sup))) }
}
def list() = Action.async {
categoriesDAO.getAll() map { cat => Ok(Json.toJson(cat)) }
}
def insertCategory = Action.async(parse.json) {
request => {
{
for {
name <- (request.body \ "name").asOpt[String]
description <- (request.body \ "description").asOpt[String]
parent_id <- (request.body \ "parent_id").asOpt[String]
} yield {
categoriesDAO.insert(Category(0, name, description, parent_id.toLong)) map { n => Ok("Id of Category Added : " + n) }
}
}.getOrElse(Future{BadRequest("Wrong json format")})
}
}
}
- BaseDAO.scala -------------------
package models.daos
import models.entities.{Supplier, BaseEntity, Category, Product}
import models.persistence.SlickTables
import models.persistence.SlickTables.{SuppliersTable, BaseTable, CategoriesTable, ProductsTable}
import play.api.Play
import play.api.db.slick.{DatabaseConfigProvider, HasDatabaseConfig}
import slick.backend.DatabaseConfig
import slick.driver.JdbcProfile
import slick.lifted.{CanBeQueryCondition}
import scala.concurrent.Future
import play.api.libs.concurrent.Execution.Implicits.defaultContext
trait AbstractBaseDAO[T,A] {
def insert(row : A): Future[Long]
def insert(rows : Seq[A]): Future[Seq[Long]]
def update(row : A): Future[Int]
def update(rows : Seq[A]): Future[Unit]
def findById(id : Long): Future[Option[A]]
def findByFilter[C : CanBeQueryCondition](f: (T) => C): Future[Seq[A]]
def deleteById(id : Long): Future[Int]
def deleteById(ids : Seq[Long]): Future[Int]
def deleteByFilter[C : CanBeQueryCondition](f: (T) => C): Future[Int]
def getAll() : Future[Seq[A]]
}
abstract class BaseDAO[T <: BaseTable[A], A <: BaseEntity]() extends AbstractBaseDAO[T,A] with HasDatabaseConfig[JdbcProfile] {
protected lazy val dbConfig: DatabaseConfig[JdbcProfile] = DatabaseConfigProvider.get[JdbcProfile](Play.current)
import dbConfig.driver.api._
protected val tableQ: TableQuery[T]
def insert(row : A): Future[Long] ={
insert(Seq(row)).map(_.head)
}
def insert(rows : Seq[A]): Future[Seq[Long]] ={
db.run(tableQ returning tableQ.map(_.id) ++= rows.filter(_.isValid))
}
def update(row : A): Future[Int] = {
if (row.isValid)
db.run(tableQ.filter(_.id === row.id).update(row))
else
Future{0}
}
def update(rows : Seq[A]): Future[Unit] = {
db.run(DBIO.seq((rows.filter(_.isValid).map(r => tableQ.filter(_.id === r.id).update(r))): _*))
}
def findById(id : Long): Future[Option[A]] = {
db.run(tableQ.filter(_.id === id).result.headOption)
}
def findByFilter[C : CanBeQueryCondition](f: (T) => C): Future[Seq[A]] = {
db.run(tableQ.withFilter(f).result)
}
def getAll : Future[Seq[A]] = {
db.run(tableQ.result)
}
def deleteById(id : Long): Future[Int] = {
deleteById(Seq(id))
}
def deleteById(ids : Seq[Long]): Future[Int] = {
db.run(tableQ.filter(_.id.inSet(ids)).delete)
}
def deleteByFilter[C : CanBeQueryCondition](f: (T) => C): Future[Int] = {
db.run(tableQ.withFilter(f).delete)
}
}