`exception during macro expansion: [error] scala.r

2019-08-06 02:51发布

问题:

I'm pretty new to Scala, Play, and Quill and I'm not sure what I'm doing wrong. I have my project split up into models, repositories, and services (and controllers, but that is not relevant for this question). Right now, I'm getting this error for the lines in my services that are making changes to the database:

exception during macro expansion:  scala.reflect.macros.TypecheckException: Can't find implicit `Decoder[models.AgentId]`. Please, do one of the following things:
1. ensure that implicit `Decoder[models.AgentId]` is provided and there are no other conflicting implicits; 
2. make `models.AgentId` `Embedded` case class or `AnyVal`.

And I'm getting this error for all the other lines in my services:

exception during macro expansion: [error] scala.reflect.macros.TypecheckException: not found: value quote

I found a similar ticket, but the same fix does not work for me (I am already requiring ctx as an implicit variable, so I can't import it as well. I'm totally at a loss and if anyone has any suggestions, I would be happy to try anything. I'm using the following versions:

  • Scala 2.12.4
  • Quill 2.3.2
  • Play 2.6.6

The code:

db/package.scala

package db

import io.getquill.{PostgresJdbcContext, SnakeCase}

package object db {
  class DBContext(config: String) extends PostgresJdbcContext(SnakeCase, config)

  trait Repository {
    val ctx: DBContext
  }
}

repositories/AgentsRepository.scala

package repositories

import db.db.Repository
import models.Agent

trait AgentsRepository extends Repository {
  import ctx._

  val agents = quote {
    query[Agent]
  }

  def agentById(id: AgentId) = quote { agents.filter(_.id == lift(id)) }

  def insertAgent(agent: Agent) = quote {
    query[Agent].insert(_.identifier -> lift(agent.identifier)
    ).returning(_.id)
  }
}

services/AgentsService.scala

package services

import db.db.DBContext
import models.{Agent, AgentId}
import repositories.AgentsRepository
import scala.concurrent.ExecutionContext

class AgentService(implicit val ex: ExecutionContext, val ctx: DBContext)
  extends AgentsRepository {
  def list: List[Agent] =
    ctx.run(agents)

  def find(id: AgentId): List[Agent] =
    ctx.run(agentById(id))

  def create(agent: Agent): AgentId = {
    ctx.run(insertAgent(agent))
  }
}

models/Agent.scala

package models

import java.time.LocalDateTime

case class AgentId(value: Long) extends AnyVal
case class Agent(
                  id: AgentId
                  , identifier: String
                )

回答1:

I am already requiring ctx as an implicit variable, so I can't import it as well

You don't need to import a context itself, but everything which is inside in order to make it work

 import ctx._

Make sure to place it before ctx.run called, as in https://github.com/getquill/quill/issues/998#issuecomment-352189214